多対多 - はじめに¶
データにおける一対多のリレーションシップを扱う方法を見てきました。
では、多対多のリレーションシップはどのように処理すればよいのでしょうか?
それらを探索してみましょう。🚀
一対多から始める¶
おなじみの、よりシンプルなオプションである一対多から始めましょう。
チームのテーブルとヒーローのテーブルがあり、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とそれらを操作するためのコードの書き方を確認しましょう。🚀