#中間テーブルって?
"join table もしくは junction table"とも呼ばれ、その名の通り、2つのテーブルの中間にもう一つ、それぞれに接続されたテーブルを指します。
↓ER図で見てみると
これが"中間テーブル"です。(ER図とは?やER図の見方はこちら)
では、簡潔にどんな時に用いるかというと
下図のように2つのテーブルの間に
" 多対多 "
という関係性が生まれた時、ある問題を解決する1つの方法としてこの中間テーブルを配置します。
多対多
の意味がなかなかわかりにくいかと思いますので、これから詳しく図解を使ってちょっとずつ掴んでいきましょう。
#1.まずは多対多のイメージ
多対多とは........
例えば、
下の画像のようなプログラミング学習サイトを製作しているとします。
このサイトではユーザーは学習したいプログラミングコースをカスタマイズして選ぶことができるとします。
おそらく必要だとされるテーブルはまずこの2つが想像できます。
1.ユーザー用のもの
2.プログラミングのコース用のもの
2つのテーブルに以下のように名前を決めて...
①usersテーブル (ユーザー情報用のテーブル)
②coursesテーブル (プログラミングの言語情報用のテーブル)
とします。
次にテーブル間の関係性をイメージします。
①usersテーブルから見ると
1userは複数のコースを持っている →→→ "対多"
②coursesテーブルから見ると
1courseは複数のユーザーを持っている →→→ "対多"
ということはusersテーブルとcoursesテーブルは
対多 + 対多 == " 多対多 "
という関係が成り立ちます。
まだよくわからないという方もいると思いますが、実際にテーブルの形で例をみてみましょう。
2. 実際に多対多のテーブルをみてみよう
とりあえずユーザー3人と言語コース3つで表示しています。
それぞれのテーブルのレコードどちらからも複数のつながりが見えます
つまり、
" 多対多 "とは関連するテーブルのidを複数お互いに持っているということです。
そして、この関係性では下図のように外部キー用のカラムが必要なので
外部キーを持たせたテーブルをみてみましょう。
多対多の関係性の一例ですが、こんな感じになるはずです。
ではもう少し詳しくみてみましょう。
3. 多対多の問題点
*前提として1カラムの中にデータは1つずつしか入れられません。
つまり、下の図のように1カラムがuser_idを複数もつことはできません。
★coursesテーブルの中身
userが増えるごとにuser_idカラムを増やさなければいけません。
・図のcoursesテーブルにはとりあえず5人分のuser_idカラムを表示させています。
注目すべきは**赤枠で囲まれたnull(空)のカラム**
ユーザー一人一人のコース選択が異なるため、図のように空のカラムを持たざるおえない状況が起きてしまいます。
★usersテーブルの中身
courseが増えた時、userの時と同じようにカラムを増やさなければいけません。
こちらもusersテーブルには8コース分までのcourse_idカラムを持たせています。
同様に**null(空)のカラム**が多数存在しています。
どこがいけないのかわからない場合はnull(からっぽ)のカラムにとりあえず注目してみてください。
なんだかボコボコ、ガタガタで、使われていないからっぽのカラムが多数ありますよね。
このような不要なカラムが多数、発生するようなテーブルは
Multi Column Attribute(マルチカラムアトリビュート)
とよばれ、DB設計において非常に良くない設計であるとされています。
では、どうしたらいいのか。
そんな時用いるのが
中間テーブル
です。
#4. 中間テーブル
実際に中間テーブルがどんな構造になっているのかもう一度最初のER図をみてみましょう。
よく見ると
中間テーブル course_usersテーブル は
それぞれ接続先のテーブルの外部キー
・user_id
・course_id
を持っています。
2.実際に多対多のテーブルをみてみようで用いた図を再び見ながら、中間テーブルを作成してみましょう。
この2つのテーブルの間に中間テーブルを設置すると下のような中間テーブルになります。
では、さらに詳しく実際の中間テーブルの中身も見てみましょう。
### 中間テーブル: course_usersテーブル
要するに今後、userの数やcourseの数が増えたとしても
この中間テーブルがあれば、**null(空)**を出すことなく、レコードを追加することができます。
###補足: usersとcoursesの中間テーブルの命名について
中間テーブルの命名は関係性を考えて作成したり、言語により制約などがありますがある程度は自由です。今回はアルファベット順に2つのテーブル名を並べ、最初のテーブルのsを取り除き、_(アンダーバー)でつなげています
なので
cousesテーブル + usersテーブル = course_usersテーブル
#まとめ
###中間テーブルの特徴まとめ
・多対多の関係性があるテーブルの間に設置
・接続する2テーブルの外部キーをもつ
・命名は〇〇〇__〇〇〇s (基本的にはアルファベット順)もしくは新しく命名
状況によっては中間テーブルをつくったほうがいいケースばかりではありませんが、中間テーブルや多対多の概念について、もやもやしている方はそれがちょっとでもクリアになってもらえたなら嬉しいです。
随時、よりわかりやすくなるよう修正、更新いたします。