web-dev-qa-db-ja.com

多対多のピボットテーブルに基づく一意のキー

アーティストとアルバムのテーブルを管理する必要があります。

| artists      |  | albums       |  | album_artist |
+--------------+  +--------------+  +--------------+
| id           |  | id           |  | id           |
| artist       |  | album        |  | album_id     |
| created_at   |  | created_at   |  | artist_id    |
| updated_at   |  | updated_at   |  +--------------+
+--------------+  +--------------+

これは多対多の関係であることを念頭に置いて、アルバムとアーティストのペアを一意にする方法を見つける必要があります。アルバムには同じ名前が付けられていても、異なるアーティストに属している可能性があるため(fe "Greatest Hits "2PacのアルバムとNotorious BIGの" Greatest Hits ")。

この問題に対処する既知の方法/パターンはありますか?

2
user197675

最も単純でおそらく最も一般的な方法は、(album_id、artist_id)列のペアを一意の複合キーとして宣言することです。

このアプローチには2つのバリエーションがあります。最初に、album_artistテーブルの現在の構造を維持し、単純に add 上記の2つの列に一意の制約を設定できます。

ALTER TABLE album_artist
ADD CONSTRAINT uq_album_artist
  UNIQUE (album_id, artist_id);

リンクされたマニュアルにあるUNIQUE制約を追加するオプションは他にもあります。

2番目のバリエーションは、id列を削除し、(album_id、artist_id)をテーブルの主キーとして宣言することです Rick James がコメントで示唆しているように:

ALTER TABLE album_artist
DROP PRIMARY KEY;  /* assuming id has actually been declared
                      as the PK; if not, omit this step */

ALTER TABLE album_artist
DROP id;

ALTER TABLE album_artist
ADD CONSTRAINT pk_album_artist
  PRIMARY KEY (album_id, artist_id);

album_artistテーブルのようなジャンクションテーブルは、テーブル参照以外の追加情報を格納せず、通常、他のテーブルから参照する必要はありません。少なくとも、専用のID列が必要です。したがって、2番目のバリエーションの方が適切な場合があります。ジャンクションテーブルの実装に関するリックの他の有用な考えは、 彼のブログ にあります。

別のテーブルが有効な組み合わせ(つまり、junctionテーブルに存在するもの)としてアルバムとアーティストを参照する必要がある場合、複合外部キーを使用してalbum_artistを参照できます。

FOREIGN KEY (album_id, artist_id) REFERENCES album_artist (album_id, artist_id)

ジャンクションテーブルを頻繁に(つまり、多くのテーブルから)参照する必要がある場合のみ、ジャンクションテーブルに専用のPK列を保持できる最初のアプローチがより有用であると私は主張します。

3
Andriy M