基于多对多数据透视表的唯一键

use*_*675 4 mysql database-design many-to-many relations

我必须管理艺术家和专辑表:

| artists      |  | albums       |  | album_artist |
+--------------+  +--------------+  +--------------+
| id           |  | id           |  | id           |
| artist       |  | album        |  | album_id     |
| created_at   |  | created_at   |  | artist_id    |
| updated_at   |  | updated_at   |  +--------------+
+--------------+  +--------------+
Run Code Online (Sandbox Code Playgroud)

请记住,这是一种多对多关系,我确实需要找到一种方法来使专辑-艺术家对唯一,因为专辑可能具有相同的名称但属于不同的艺术家(例如“Greatest Hits”) ” 2Pac 专辑和 Notorious BIG 的“Greatest Hits”)。

是否有已知的方法/模式来解决这个问题?

And*_*y M 5

最简单也可能是最常见的方法是声明(album_id, Artist_id)对列声明为唯一的组合键。

\n\n

这种方法有两种变体。首先,您可以保留album_artist表的当前结构并简单地添加唯一约束:

\n\n
ALTER TABLE album_artist\nADD CONSTRAINT uq_album_artist\n  UNIQUE (album_id, artist_id);\n
Run Code Online (Sandbox Code Playgroud)\n\n

还有更多添加 UNIQUE 约束的选项,可以在链接的手册中找到。

\n\n

第二种变体是去掉id列并声明(album_id, Artist_id)为表的主键,如Rick James在评论中建议的那样:

\n\n
ALTER TABLE album_artist\nDROP PRIMARY KEY;  /* assuming id has actually been declared\n                      as the PK; if not, omit this step */\n\nALTER TABLE album_artist\nDROP id;\n\nALTER TABLE album_artist\nADD CONSTRAINT pk_album_artist\n  PRIMARY KEY (album_id, artist_id);\n
Run Code Online (Sandbox Code Playgroud)\n\n

像album_artist表这样的联结表,除了表引用之外不存储其他信息,通常不需要被其他表 \xe2\x80\x93 至少引用,通常不足以证明需要专用 ID 列。因此,第二种变体可能更合适。Rick 关于实现连接表的其他有用的想法可以在他的博客中找到。

\n\n

如果另一个表需要引用专辑和艺术家作为有效组合(即存在于连接表中的组合),它可以简单地使用复合外键来引用album_artist

\n\n
FOREIGN KEY (album_id, artist_id) REFERENCES album_artist (album_id, artist_id)\n
Run Code Online (Sandbox Code Playgroud)\n\n

只有当您需要经常引用连接表(即,从许多表)时,我认为第一种方法(允许您在连接表中保留专用的 PK 列)才会更有用。

\n