多对多表应该有主键吗?

时间:2010-12-21 21:00:49

标签: database many-to-many database-agnostic

如果我有两个具有多对多关系的对象,我通常会在我的数据库模式中使用多对多表对它们进行建模,以使两者相关联。但是,多对多表(或“连接表”)是否有自己的主键(整数自动递增)?

例如,我可能有表A和B,每个表都有一个ID,还有一个名为A_B的表,其外键元组为(A_ID,B_ID)。但是,A_B是否应该拥有自己的主键自动递增ID列?

添加它有哪些优缺点?我个人喜欢用于多对多连接的自然键。但主要关键是什么增加了好处呢?

6 个答案:

答案 0 :(得分:19)

我同意Oded所说的一切,除了

  

“它不能合理地用作   外键要么。“

在这种情况下,它是一个选择你的毒药,映射表绝对可以是父母,这只是孩子使用多列FK的问题。

简单介绍一下Car和color。每年的汽车制造商都有一定的颜色托盘,每个型号只有有限数量的颜色。许多 - 很多::颜色到汽车模型

所以现在设计Order表,其中存储了新车订单。显然,Color和Model将在Order表上。如果对这些表中的每个表生成FK,则数据库将允许选择不正确的模型/颜色组合。 (当然,您可以使用代码强制执行此操作,但不能以声明方式执行此操作。)如果您将父项设置为many:many表,则只能获得已指定的组合。

那你想要一个多列FK并指向一个建立在ModelID和ColorID上的PK,或者你想要一个列FK吗?

选择你的毒药。

修改

但如果它不是某事物的父母,那么任何表都不需要代理键。

答案 1 :(得分:11)

除了开销之外,这样的代理键不会增加任何内容。

如果您关心此表中的重复,请使用自然键,使它们成为复合主键。

扩展:

在应用程序中,此密钥将毫无意义,并将保持未使用状态。

在数据库中,它没有任何功能,因为你无法在查询中合理地使用它来获得任何类型的有意义的结果。

它也不能合理地用作外键。

答案 2 :(得分:2)

如果跟踪多对多关系的表具有其自己的主键,并且该键用作数据库中其他任何地方的外键,则您将创建对该关系的依赖关系。这种关系永远无法消除。

例如,在汽车颜色示例中,如果汽车的颜色曾经被中断(从多对多关系表中删除),那么任何引用主键的表(即购买历史记录)都会被破坏。

答案 3 :(得分:1)

我已经做到了两个方面。有时在路上添加功能是有益的。例如,如果曾经有一段时间表中的行包含的内容不仅仅包含2个id。如果你没有空间我会把它放在那里因为它不会伤害。有时它会干扰像hibernate或ADO.NET这样的ORM工具,但这很小。

总结一下...... PROS 1.允许未来的潜在增长。

CONS 1.空间 2.混淆一些ORM工具。

答案 4 :(得分:1)

经常使用术语“连接表”,但我认为我没有看到它被正确定义或解释过。我个人避免使用该术语。据我了解,“连接表”表示任何具有两个外键(或可能超过两个?)的表。

我认为在具有多个外键的表中选择键的标准应该与任何其他表中的标准大致相同。问问自己,你需要强制执行什么依赖,什么是独特的和不可简化的。按照熟悉,稳定和简洁的标准选择键。只有在有充分理由的情况下才能添加代理键。

答案 5 :(得分:0)

它并没有真正提供任何有用的东西。请记住密钥的用途,即唯一引用“某事”。像这样的关联表本身并不是“某种东西”,而是另外两个已经拥有密钥的“东西”的持久性结构。在持久性介质(数据库)之外,它没有意义,甚至不应该存在或被知道(例如在业务领域中),因此(应该)永远不会成为引用它的理由它自己的ID。