2010-12-21 55 views
25

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

例如,我可能具有表A和B,每一个ID,并且具有(A_ID,B_ID)的外键元组的表中调用A_B。但是,A_B应该有一个自己增加了主键的ID列,还是没有?

添加它有哪些优缺点?我个人喜欢用于多对多连接的自然键。但主键添加会带来什么好处?

+1

http://stackoverflow.com/questions/2190272/sql-many-to-many-table-primary-key的副本。 – 2010-12-21 21:09:59

+0

我们应该删除这个问题吗? – ashes999 2010-12-21 21:30:44

回答

17

我同意一切,除了

奥德说:“这不能合理地或者用作 外键。”

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

以汽车和颜色为例。每年Auto Makers都有一定的托盘颜色,每种型号只能使用有限数量的这些颜色。许多 - 许多::颜色到汽车模型

所以现在的设计,其中新订单的汽车存储Order表。清晰的颜色和模型将在订单表上。如果您为每个表格创建FK,则数据库将允许选择不正确的模型/颜色组合。 (当然,你可以用代码来强制执行,不能用声明方式强制执行。)如果你让父对象成为many:many表,你只会得到已经指定的组合。

那么你愿意有一个多列FK,并指向建立在ModelID和ColorID上的PK,还是你想要一个单列FK?

挑你的毒药。

编辑

但是,如果它不是的东西父母,没有表需要一个代理键。

10

这样的代理键除了开销之外什么都不加。

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

要展开:

在应用中,这关键将是毫无意义的,将继续使用。

在数据库中,它不会有任何作用,因为你不能合理地使用它在查询的任何类型的有意义的结果的。

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

+0

是的,我能看到的唯一用途是,如果你想限制删除到一个记录 - 但是这会导致额外的ID查找,假设你有两个外键ID。我同意。 – ashes999 2010-12-21 21:30:00

+1

@ ashes999 - 你不应该在这张表(或者任何表格)中有重复的行。如果你不这样做,那么删除一行将只需要两个外键。 – Oded 2010-12-21 21:33:51

0

它并没有提供任何有用的东西。请记住钥匙的目的,即唯一指“某物”。像这样的关联表本身不是“某种东西”,而是两个已经有键的其他“事物”的持久性结构。除了持久性媒介(数据库)之外,它没有意义,甚至不应该真正存在或不被知道(例如在业务领域),所以不应该有理由指称它它自己的ID。

+0

正是我的论点。真实对象应该有ID来标识它们。 – ashes999 2010-12-21 21:30:23

1

我已经完成了这两种方法。有时在路上添加功能是有益的。例如,如果有一段时间表格中的某一行将不止包含任何2个id以上的内容。如果你没有空间,我会把它放在那里,只是因为它不会受伤。有时它可能会干扰像休眠或ADO.NET这样的ORM工具,但这很小。

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

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

1

术语“连接表”经常被使用,但我认为我从未见过它正确定义或解释。我个人避免使用这个术语。据我所知,“连接表”是指任何带有两个外键(或可能多于两个?)的表。

我认为用多个外键选择表中的键的标准应该和其他表中的相同。问问你自己需要执行哪些依赖关系,什么是独特的和不可约的。选择熟悉度,稳定性和简单性标准的按键。只有当你有充分的理由时才添加代理键。