MS SQL 使用联结表创建多对多关系

Posted

技术标签:

【中文标题】MS SQL 使用联结表创建多对多关系【英文标题】:MS SQL creating many-to-many relation with a junction table 【发布时间】:2013-01-18 12:55:52 【问题描述】:

我正在使用 Microsoft SQL Server Management Studio,在创建联结表时,我是否应该为联结表创建一个 ID 列,如果是,我是否也应该将其设为主键和标识列?还是只为我要加入多对多关系的表保留 2 列?

例如,如果这是多对多表:

MOVIE
Movie_ID
Name
etc...

CATEGORY
Category_ID
Name
etc...

我应该制作联结表吗:

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID
Movie_Category_Junction_ID

[将Movie_Category_Junction_ID设为我的主键并将其用作身份列]?

或者:

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID

[并且没有主键或身份表就让它保持原样] ?

【问题讨论】:

【参考方案1】:

对此有不同的思想流派。一所学校更喜欢包含一个主键并将链接表命名为比它链接的两个表更重要的东西。原因是,虽然该表可能一开始看起来只是一个链接表,但它可能会成为包含重要数据的自己的表。

一个例子是杂志和订阅者之间的多对多。实际上,该链接是具有自己属性的订阅,例如到期日期、付款状态等。

但是,我认为有时链接表只是一个链接表。与类别的多对多关系就是一个很好的例子。

所以在这种情况下,不需要单独的一个字段主键。您可以拥有一个自动分配键,这不会造成任何伤害,并且可以更轻松地删除特定记录。作为一般做法,这可能很好,因此如果该表后来发展为具有自己重要数据(作为订阅)的重要表,它将已经具有自动分配的主键。

您可以在两个字段上放置唯一索引以避免重复。如果您有单独的自动分配键,这甚至可以防止重复。您可以将这两个字段用作主键(这也是唯一索引)。

因此,一种思想可以坚持使用整数自动分配主键,并避免复合主键。这不是唯一的方法,也可能不是最好的方法,但它不会让你误入歧途,导致你真正后悔的问题。

但是,对于您正在做的事情,您可能只使用这两个字段就可以了。我仍然建议将这两个字段设为复合主键,或者至少在这两个字段上放置一个唯一索引。

【讨论】:

【参考方案2】:

我会选择第二个连接表。但是将这两个字段设为主键。这将限制重复条目。

【讨论】:

【参考方案3】:

我会使用第二个联结表:

MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID

主键是两列的组合。您还将有一个从每一列到 MovieCategory 表的外键。

联结表如下所示:

create table movie_category_junction
(
  movie_id int,
  category_id int,
  CONSTRAINT movie_cat_pk PRIMARY KEY (movie_id, category_id),
  CONSTRAINT FK_movie 
      FOREIGN KEY (movie_id) REFERENCES movie (movie_id),
  CONSTRAINT FK_category 
      FOREIGN KEY (category_id) REFERENCES category (category_id)
);

见SQL Fiddle with Demo。

使用这两个字段作为PRIMARY KEY 将防止重复的电影/类别组合被添加到表中。

【讨论】:

我也会做同样的事情。添加第三列可以有重复的记录。 这种情况下是否需要创建复合主键? @Harry.Naeem 如果你不这样做,那么你很容易在表中得到重复的记录。我不认为你会想要那个。 @bluefeet 我已经创建了一个包含两个外键的表,我应该同时选择它们并在 sql server 中设置为主键吗? @Harry.Naeem 在不知道所有细节的情况下,我只是猜测,所以我建议you post a new question 并提供您的表结构的详细信息,可能还有一些示例数据。您可能会从中得到更清晰的答案,然后通过我对您当前设置的猜测。

以上是关于MS SQL 使用联结表创建多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

数据库优先方法中与联结表的多对多关系

通过联结表进行多对多自连接

通过链接到SQL Server数据库的MS Access以多对多关系插入数据(中间表)

多个多对多关系(循环关系)

如何在实体关系图中表示联结表?

查询是不是存在多个多对多关系