Database 多对多表是否应该有主键?

Database 多对多表是否应该有主键?,database,many-to-many,database-agnostic,Database,Many To Many,Database Agnostic,如果我有两个具有多对多关系的对象,我通常会在数据库模式中使用多对多表对它们进行建模,以将两者关联起来。但多对多表(或“联接表”)是否应该有自己的主键(整数自动递增) 例如,我可能有表A和表B,每个表都有一个ID,还有一个名为A_B的表,它的外键元组为(A_ID,B_ID)。但A_B是否应该有自己的主键自动递增ID列 添加它的优点和缺点是什么?我个人喜欢多对多连接的自然键。但是主键会增加什么好处呢?这样的代理键只会增加开销 如果您关心此表中的重复,请使用自然键,使其成为复合主键 要扩展: 在应用程

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

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


添加它的优点和缺点是什么?我个人喜欢多对多连接的自然键。但是主键会增加什么好处呢?

这样的代理键只会增加开销

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

要扩展:

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

在数据库中,它将没有任何功能,因为您不能在查询任何类型的有意义的结果时合理地使用它


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

它实际上没有提供任何有用的东西。请记住键的用途是唯一地引用“某物”。像这样的关联表本身不是“某物”,而是另外两个已经有键的“某物”的持久化结构。在持久性介质(数据库)之外,它没有任何意义,甚至不应该真正存在或为人所知(例如在业务领域),因此永远没有理由通过它自己的ID来引用它。

我用两种方法都做过。有时,在以后添加功能是有益的。例如,如果曾经有一次表中的一行包含的内容超过了2个id。如果你不缺少空间,我会放一个进去,因为它不会痛。有时它会干扰诸如hibernate或ADO.NET之类的ORM工具,但这是次要的

总而言之。。。 赞成的意见 1.允许潜在的未来增长

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

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

“它不能合理地用作 外键也可以。”

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

以汽车和颜色为例。每年汽车制造商都有一定的颜色托盘,每种型号的颜色数量有限。多-多::汽车模型的颜色

因此,现在设计订单表,用于存储新车订单。显然,颜色和型号将在订单表上。如果对每个表进行FK,则数据库将允许选择不正确的模型/颜色组合。(当然可以用代码强制执行,但不能声明性地执行。)如果将父表设为多:多表,则只能得到已指定的组合

那么,您是希望使用多列FK并指向基于ModelID和ColorID构建的PK,还是希望使用单列FK

选择你的毒药

编辑

但是,如果它不是某个对象的父对象,则任何表都不需要代理键。

经常使用术语“联接表”,但我认为我从未见过对其进行正确定义或解释。就我个人而言,我避免使用这个词。据我所知,“联接表”是指任何具有两个外键(或者可能超过两个?)的表


我认为在具有多个外键的表中选择键的标准应该与在任何其他表中选择键的标准大致相同。问问自己需要强制执行哪些依赖项,哪些是唯一的和不可还原的。根据熟悉、稳定和简单的标准选择关键点。只有在有充分理由时才添加代理键。

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


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

重复。我们是否应该删除此问题?关于潜在的未来增长,请注意,只要将有意义的数据添加到关联表中,它就不仅仅是持久性逻辑。它成为自己的实体。这可能会在域中引起头痛。我认为最好将业务实体与持久性逻辑分开,并将它们分开。如果您需要向关联表中添加数据,请从更广泛的角度重新思考您正在做什么,以及是否有更好的方法,因为逻辑影响大于向表中添加列。我同意。虽然很难想象M:M关系会变成一个具有唯一主键的实体,但公平地说,我从来没有因为这样做而头疼过。我有一些实体充当了包含其他有用数据的M:M关系。这些数据有时会在它自己的网页上编辑,在那里只需要一个ID就可以了。我明白你的意思了。例如,一个允许多个作者的博客可以有一个authors_post表,其中有一个(后来添加的)author_added_on_date字段,这样我们就可以返回到修订版本,查看何时谁拥有权限。嗯。我仍然会说“在需要时添加代理密钥,而不是在之前。”啊,999-是的,这正是我所指的那种情况。我同意,如果你需要的话,你可以随时添加一条。是的,我能看到的唯一用途是,如果你想将删除限制为一条记录——但如果你同时拥有两个外键ID,那会导致额外的ID查找。我同意。@ashes999-您不应该在这个表(或任何一个表,例如)中有重复的行