多対多 - はじめに¶
データにおける一対多のリレーションシップを扱う方法を見てきました。
では、多対多のリレーションシップはどのように処理すればよいのでしょうか?
それらを探索してみましょう。🚀
一対多から始める¶
おなじみの、よりシンプルなオプションである一対多から始めましょう。
チームのテーブルとヒーローのテーブルがあり、1つのチームごとに多数のヒーローを所属させることができます。
各チームには複数のヒーローを所属させることができるため、team
テーブルのすべての列にヒーローIDを配置することはできません。
しかし、各ヒーローは1つのチームにのみ所属できるため、ヒーローテーブルには特定のチーム(team
テーブルの特定の行)を指す単一の列があります。
team
テーブルは次のようになります。
id | name | headquarters |
---|---|---|
1 | Preventers | Sharp Tower |
2 | Z-Force | Sister Margaret's Bar |
ヒント
他のテーブルへの外部キーがないことに注目してください。
そして、hero
テーブルは次のようになります。
id | name | secret_name | age | team_id |
---|---|---|---|---|
1 | Deadpond | Dive Wilson | null | 2 |
2 | Spider-Boy | Pedro Parqueador | null | 1 |
3 | Rusty-Man | Tommy Sharp | 48 | 1 |
hero
テーブルには、team
テーブルの特定のチームのIDを指すteam_id
列があります。
これが、各hero
をteam
と接続する方法です。
各ヒーローは1つの接続しか持てないことに注意してください。ただし、各チームは多数の接続を受け取ることができます。特に、チームのPreventersには2人のヒーローがいます。
多対多を紹介する¶
しかし、Deadpondが素晴らしいキャラクターなので、彼を新しいPreventersチームに採用したが、彼はZ-Forceチームにも所属しているとしましょう。
したがって、ここでは、多数のチームに接続されたヒーローを持つことができる必要があります。そして、各チームは依然として多数のヒーローを受け取ることができる必要があります。したがって、多対多のリレーションシップが必要になります。
あまりうまくいかない単純なアプローチは、hero
テーブルに列を追加することです。追加の2つの列を追加すると想像してください。これで、1人のhero
を合計3つのチームに接続できますが、それ以上はできません。したがって、多数のチームをサポートするという問題を解決したわけではなく、非常に限られた固定数のチームのみをサポートしていることになります。
もっと良い方法があります!🤓
リンクテーブル¶
hero
テーブルとteam
テーブル間のリンクを表す別のテーブルを作成できます。
このテーブルには、hero_id
とteam_id
の2つの列だけが含まれています。
両方の列は、hero
テーブルとteam
テーブルの特定の行のIDを指す外部キーです。
これはhero-team-linkを表すため、テーブルをheroteamlink
と呼びましょう。
次のようになります。
ここで、テーブルhero
にteam_id
列がなくなったことに注意してください。このリンクテーブルに置き換えられました。
そして、team
テーブルには、以前と同様に、外部キーもありません。
具体的には、新しいリンクテーブルheroteamlink
は次のようになります。
hero_id | team_id |
---|---|
1 | 1 |
1 | 2 |
2 | 1 |
3 | 1 |
team_id
このリンクテーブルに使用される他の名前は次のとおりです。
- アソシエーションテーブル
- セカンダリテーブル
- ジャンクションテーブル
- 中間テーブル
- 結合テーブル
- スルーテーブル
- リレーションシップテーブル
- 接続テーブル
私は、「リンクテーブル」という用語を使用しています。これは短く、既に使用されている他の用語(「リレーションシップ」など)と衝突せず、書き方を覚えやすいからです。
リンク主キー¶
素晴らしい、2つの列のみを持つリンクテーブルがあります。しかし、SQLデータベースでは、各行が、そのテーブル内の行を一意に識別する主キーを持つ必要があることを覚えておいてください。
では、このテーブルの主キーは何でしょうか?
各固有の行をどのように識別すればよいのでしょうか?
このリンクテーブルの主キーになる別の列を追加する必要がありますか?いいえ!そうする必要はありません。👌
両方の列がこのテーブルの各行の主キーです。(そして、各行にはそれらの2つの列だけがあります。)✨
主キーは、単一のテーブル内の特定の行を一意に識別する方法です。ただし、単一の列である必要はありません。
主キーは、テーブル内の列のグループにすることができ、それらの組み合わせはこのテーブルで一意です。
上記の表をもう一度確認してください。各行にはhero_id
とteam_id
の一意の組み合わせがあることがわかりますか?
重複した主キーを持つことはできません。つまり、hero
とteam
の間で重複したリンクを持つことはできません。まさに私たちが望んでいることです!
たとえば、データベースは、重複した行を持つ次のようなエラーを防止します。
hero_id | team_id |
---|---|
1 | 1 |
1 | 2 |
2 | 1 |
3 | 1 |
3 🚨 | 1 🚨 |
ヒーローが同じチームに2回所属することは意味がないですよね?
ここで、このテーブルの主キーとして2つの列を使用するだけで、SQLはhero
とteam
の間のリンクを重複させないようにします。✅
まとめ¶
まとめ付きのイントロ!それは奇妙ですが...まあいいでしょう。🤷
これで、多対多のリレーションシップに関する理論と、SQLのテーブルでそれらを解決する方法がわかりました。🤓
次に、SQLとそれらを操作するためのコードの書き方を確認しましょう。🚀