SQL - 多对多表主键

时间:2010-02-03 07:14:47

标签: sql primary-key many-to-many

在这个问题中阅读评论之后出现了这个问题:

Database Design

创建多对多表时,是应该在两个外键列上创建复合主键,还是创建自动增量代理“ID”主键,并将索引放在两个FK列上(也许是一个独特的约束)?在每种情况下插入新记录/重新索引的性能有何影响?

基本上,这个:

PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)

VS。这样:

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
评论者说:

  

将PK表示为两个ID   表在磁盘上进行物理排序   以该顺序。所以,如果我们插入   (Part1 / Device1),(Part1 / Device2),   (Part2 / Device3),然后(第1部分/ Device3)   数据库将不得不打破   分开并插入最后一个   在条目2和3之间。对许多人而言   记录,这变得非常有问题   因为它涉及洗牌数百,   数千或数百万条记录   每次添加一个。相比之下,   自动增量PK允许新的   记录要写到最后。

我问的原因是因为我一直倾向于使用没有代理自动增量列的复合主键,但我不确定代理键是否实际上更具性能。

5 个答案:

答案 0 :(得分:75)

通过简单的两列多对多映射,我发现拥有代理键​​并没有什么优势。在(col1,col2)上拥有主键是唯一的(假设引用表中的col1col2值是唯一的)并且(col2,col1)上的单独索引将捕获那些情况相反的顺序会执行得更快。代理是浪费空间。

您不需要单个列的索引,因为该表只应该用于将两个引用的表连接在一起。

在我看来,你在问题中提到的那个评论不值得它使用的电子。听起来像作者认为表存储在一个数组中,而不是一个极高性能的平衡多路树结构。

首先,从来没有必要存储或获取排序,只是索引。并且索引将不会存储顺序,它将以有效的方式存储,以便能够快速检索。

此外,绝大多数数据库表的读取次数比写入的更多。这使得你在选择方面做的任何事情都比插入方面的任何东西都更有意义。

答案 1 :(得分:16)

链接表不需要代理键。

你需要一个PK(col1,col2)和另一个唯一索引(col2,col1)

除非您使用的ORM无法应对并决定您的数据库设计......

编辑:我在这里回答:SQL: Do you need an auto-incremental primary key for Many-Many tables?

答案 2 :(得分:11)

如果引用了表,则可能需要增量主键。多对多表中可能存在需要使用增量主键从另一个表中提取的详细信息。

例如

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details

使用PartDevice.ID作为FK很容易拉出“其他细节”。因此,需要使用增量主键。

答案 3 :(得分:6)

我能回答你问题的最简单,最直接的方法是,如果你链接的两个表没有连续的主键,会对性能产生影响。如您所述/引用的那样,链接表的索引将变为碎片,或者如果链接表没有自己的顺序主键,DBMS将更加努力地插入记录。这就是大多数人在链接表上放置顺序递增主键的原因。

答案 4 :(得分:2)

因此,似乎如果唯一的工作是链接两个表,则最好的PK将是双列PK。

但是,如果它有其他用途,则添加另一个NDX作为带有外键和第二个唯一索引的PK。

索引或PK是确保没有重复项的最佳方法。 PK使Microsoft Management Studio之类的工具可以为您完成一些工作(创建视图)