中間テーブルとは
テーブルとテーブルの多対多の関係を表す関連テーブルです。
そう言われてもこの情報だけではさっぱりわからず。
先輩の説明を受けてスッキリ理解できましたので、以下に実例を踏まえてまとめます。
親子の関係
userとschoolの2つのテーブルがあるとします。
| id | user |
|---|---|
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 〜 | 〜 |
| id | school |
|---|---|
| 1 | A小学校 |
| 2 | B中学校 |
| 3 | C高校 |
| 4 | D大学 |
| 〜 | 〜 |
この2つのテーブルからユーザーの学歴を表現してみようと思います。
最終卒業の学歴を表すだけでいいのなら、userテーブルにカラムを足すだけで解決します。
| id | user | school_history |
|---|---|---|
| 1 | a | D大学 |
| 2 | b | D大学 |
| 3 | c | C高校 |
| 4 | d | B中学校 |
この時、それぞれのuserが持っているschoolの情報は一つだけです。
schoolからみると、複数のユーザーを持つことができます。
この状態を指して、schoolが親テーブル、userが子テーブル、のように「親子関係」と呼びます。
親・・・相手のテーブルに対して複数情報を持つ
子・・・相手のテーブルに対してひとつ情報を持つ
多対多の関係
同じ例で、すべての学歴を表現しようとすると
| id | user | school1 | school2 | school3 | school4 |
|---|---|---|---|---|---|
| 1 | a | A小学校 | B中学校 | C高校 | D大学 |
| 2 | b | A小学校 | B中学校 | D大学 | |
| 3 | c | A小学校 | B中学校 | C高校 | |
| 4 | d | B中学校 | |||
| こんな感じになります。 | |||||
| カラムが一気に増えましたね。 |
userも複数のschoolを持っていて、
<aさんはA小学校〜D大学>
schoolも複数のuserを持っています。
<B中学校はaさん、bさん、cさん>
このような状況を多対多の関係と呼びます。
ここで4年制大学卒業後、更に進学したユーザーを想定すると、さらにカラムが増えます。
| id | user | school1 | school2 | school3 | school4 | school5 | school6 |
|---|---|---|---|---|---|---|---|
| 1 | a | A小学校 | B中学校 | C高校 | D大学 | ||
| 2 | b | A小学校 | B中学校 | D大学 | |||
| 3 | c | A小学校 | B中学校 | C高校 | |||
| 4 | d | B中学校 | |||||
| 5 | e | A小学校 | B中学校 | C高校 | D大学 | E大学院 | Foreign_University |
こうなった場合に、以下の2つの問題が発生してきます。
1. 設計時にいくつカラムを用意しておけばいいか、想定が難しい。
このやり方では、卒業履歴がどこまで伸びるか完全に想定しきる必要があります。多くの場合、現実的ではありません。
2.データが入っていない項目が増えてきた
実際にデータを処理する際に空の情報はエラーの元となります。可能なら扱いたくありません。
中間テーブルのススメ
そこで、中間テーブルが大変便利です。
user
| id | user |
|---|---|
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 〜 | 〜 |
school
| id | school |
|---|---|
| 1 | A小学校 |
| 2 | B中学校 |
| 3 | C高校 |
| 4 | D大学 |
| 5 | E大学院 |
| 6 | Foreign_University |
| 〜 | 〜 |
user_school ←中間テーブル new!!
| id | user | school |
|---|---|---|
| 1 | a | A小学校 |
| 2 | a | B中学校 |
| 3 | a | C高校 |
| 4 | a | D大学 |
| 5 | b | A小学校 |
| 6 | b | B中学校 |
| 〜 | 〜 |
userにカラムを追加するやり方では、空欄たっぷりの表が学校情報の追加に合わせて際限なく伸びていましたが、
userとschoolの関係だけを記述していく「中間テーブル」を作成することで
・どちらかのテーブル情報が増えてもカラムを足す必要がない
・不要な空欄の発生が防げる
・中間テーブルを見ることで、それぞれのユーザーの学歴が表現できている
これで、データの種類が増えていく想定まで見越したデータベースが設計できました。
今日はこのあたりで失礼します。
参考サイト
【初心者・独学者向け】Ruby On Railsで中間テーブルを作成し、多対多を実現する
https://programming-beginner-zeroichi.jp/articles/25
Rails Guide Active Record の関連付け (アソシエーション)
https://railsguides.jp/association_basics.html