テーブル間の多重度とJOIN句の関係性

## はじめに
こんにちは。リンクアンドモチベーションの柳です。

本記事はリンクアンドモチベーション Advent Calendar 2023の10日目の記事です。

https://qiita.com/advent-calendar/2023/lmi

先日、先輩にJOIN句を使用する際に、「JOINするテーブル間の多重度を意識している」という話を聞きました。
そのため、本記事では、DBのテーブルの多重度とJOIN句の関係性について学んだことを共有します。
SQLについて学びたてのみなさん、是非読んでいってください！

## 多重度とは何か？
これから多重度について説明するにあたり、以下の定義を使用します。

> UMLでは、それらのインスタンスにおける多重度をクラス間の両端に記述することができる。多重度とは、その関連に参加するオブジェクトの数を示すものである。

[ウィキペディアより引用](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%B9%E5%9B%B3#%E5%A4%9A%E9%87%8D%E5%BA%A6)

難しいですね。
では、以下のような具体例について考えてみましょう！

![スクリーンショット 2023-12-09 17.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/50b2af6c-3148-4681-7fbb-21dd015a8621.png)

左のテーブルは、企業に関する情報を格納するテーブルです。
右のテーブルは、従業員に関する情報を格納するテーブルです。このテーブルはカラム（項目）として、その従業員がどの企業に所属しているのかを示すcompany_idを所有しています。

例えば、A株式会社という企業に、従業員として山田一郎さん、山田二郎さん、山田三郎さんが所属しているとします。
companiesテーブルに「A株式会社」（1レコード）が、employeesテーブルに「山田一郎」「山田二郎」「山田三郎」（3レコード分）が格納されています。
この時、employeesテーブルの「山田一郎」「山田二郎」「山田三郎」の3レコードは、カラムcompany_idとして「A株式会社」を示すcompany_id（=1）を所有します。

【companiesテーブル】
![スクリーンショット 2023-12-09 18.47.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/769cc650-de76-d4ea-cf64-c5bc7e818210.png)

【employeesテーブル】
![スクリーンショット 2023-12-09 18.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/128adc11-3970-c891-5fdf-c63380e57474.png)

companiesテーブルの1レコード「A株式会社」に関連するレコードが、employeesテーブルには3レコード（「山田一郎」「山田二郎」「山田三郎」）存在するということです。

つまり、companiesテーブルとemployeesテーブルは、companiesテーブルの1レコードとemployeesテーブルの複数（1つ以上）のレコードが関連するということです。これを1対nの関係と呼びます。

このような、テーブル同士の関連の構造（1対n、1対1等）を示すものを多重度です！

## 1対nの関係とJOIN句の関係性
では、なぜJOIN句を使用する際に多重度を意識すると良いのでしょうか？
ここからは、多重度の一つである1対nの関係とJOIN句の関係性についてまとめていきます。

これ以降、1対nの関係において1レコードを所有する方のテーブルを「1のテーブル」、複数のレコードを所有するテーブルを「nのテーブル」とします。

### 1のテーブルにnのテーブルをJOINする
1のテーブル（companyテーブル）にnのテーブル（employeeテーブル）をJOINしてみましょう！
結合前のcompanyテーブルは以下のようになっています。

![スクリーンショット 2023-12-09 18.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/ce906ea8-f31d-8b9d-211d-59204fa807d2.png)

companyテーブルにemployeeテーブルをJOINすると以下のような実行結果になります。

![スクリーンショット 2023-12-09 18.29.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/c6a2aa6b-880b-a3a0-96dc-97ab1ebcf52b.png)

レコード数が3行から10行に増えていることがわかりますね。

### nのテーブルに1のテーブルをJOINする
nのテーブル（employeeテーブル）に1のテーブル（companyテーブル）をJOINしてみましょう！
結合前のemployeeテーブルは以下のようになっています。

![スクリーンショット 2023-12-09 18.29.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/374896aa-155a-f3ee-b6cc-c52e7f5da623.png)

employeeテーブルにcompanyテーブルをJOINすると以下のような実行結果になります。

![スクリーンショット 2023-12-09 18.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512332/d8c93bd4-90d0-7535-3c38-6e44731b25cd.png)

レコード数が変わらず10行のままであることがわかりますね

つまり、1のテーブルにnのテーブルをJOINすると、レコード数が増える（nのテーブルに1レコードしか存在しない場合は変わらない）が、nのテーブルに1のテーブルをJOINすると、レコード数は変わらないことがわかりましたね。

## まとめ
以上より、1のテーブルにnのテーブルをJOINすると、レコード数が増える（nのテーブルに1レコードしか存在しない場合は変わらない）が、nのテーブルに1のテーブルをJOINすると、レコード数は変わらないことがわかりました。

確かに、1のテーブルにnのテーブルをJOINする際には注意が必要ですね。
実行結果のレコード数を絞るためにテーブルをJOINしたつもりが、逆に増やしてしまっていたなんてことが起きるかもしれません。
そういった際は、必要なレコードだけになるよう、WHERE句を適切に活用していきましょう！

今回は簡単な例であるためわかりやすいですが、テーブル数が多くなり、実行結果としてレコード数が数えいれないほど表示されている時には見逃してしまう観点でした。
是非、皆さんもJOINをする際は、JOINする2つのテーブルの多重度を意識していきましょう！