阅读此问题中的评论后出现此问题:
当您创建一个多对多表时,您应该在两个外键列上创建一个复合主键,还是创建一个自动增量代理“ID”主键,然后在您的两个 FK 列上放置索引(也许一个唯一的约束)?在每种情况下插入新记录/重新索引对性能有何影响?
基本上,这是:
PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)
与这个:
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
评论者说:
将这两个 ID 设为 PK 意味着该表在磁盘上按该顺序物理排序。因此,如果我们插入 (Part1/Device1)、(Part1/Device2)、(Part2/Device3),那么 (Part 1/Device3) 数据库将不得不将表分开并在条目 2 和 3 之间插入最后一个。对于许多记录,这变得非常有问题,因为它涉及到每次添加一条记录时都会打乱数百、数千或数百万条记录。相比之下,自动增量 PK 允许将新记录添加到末尾。
我问的原因是因为我一直倾向于使用没有代理自动增量列的复合主键,但我不确定代理键是否实际上更具性能。
通过简单的两列多对多映射,我认为拥有代理键没有真正的优势。 (col1,col2)
上的主键保证唯一(假设您引用的表中的 col1
和 col2
值是唯一的),并且 (col2,col1)
上的单独索引将捕获相反顺序执行更快的情况。代理是浪费空间。
您不需要单独列的索引,因为该表只能用于将两个引用的表连接在一起。
在我看来,你在问题中提到的那条评论不值得它使用的电子。听起来作者认为表是存储在数组中,而不是性能极高的平衡多路树结构。
首先,不需要存储或获取已排序的表,只需索引即可。并且索引不会按顺序存储,它会以一种有效的方式存储,以便能够快速检索。
此外,绝大多数数据库表的读取频率远高于写入频率。这使得您在选择端所做的任何事情都比在插入端做的任何事情都更相关。
链接表不需要代理键。
(col1, col2) 上的一个 PK 和 (col2, col1) 上的另一个唯一索引就是您所需要的
除非您使用的 ORM 无法应对并决定您的数据库设计......
编辑:我在这里回答了同样的问题:SQL: Do you need an auto-incremental primary key for Many-Many tables?
(col2, col1)
不是 (col1, col2)
。 (col1, col2)
的 PK 可能不适用于所有查询并生成扫描,因此使用相反的方法可以提高性能,因为它允许寻找 col2 更好的位置。例如,带有 col2 的表具有删除时的 FK 验证。检查子表 smuts
如果引用了表,则可能需要增量主键。多对多表中可能存在需要使用增量主键从另一个表中提取的详细信息。
例如
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details
使用 PartDevice.ID 作为 FK 很容易提取“其他详细信息”。因此需要使用增量主键。
我可以回答您的问题的最短和最直接的方法是说,如果您要链接的两个表没有顺序主键,则会对性能产生影响。正如您所说/引用的那样,如果链接表没有自己的顺序主键,链接表的索引将变得碎片化,或者 DBMS 将更加努力地插入记录。这就是大多数人在链接表上放置顺序递增主键的原因。
因此,如果唯一的工作是链接两个表,那么最好的 PK 将是双列 PK。
但如果它用于其他目的,则添加另一个 NDX 作为具有外键和第二个唯一索引的 PK。
索引或 PK 是确保没有重复项的最佳方式。 PK 让 Microsoft Management Studio 等工具为您完成一些工作(创建视图)
insert
将很重要。您不能仅仅因为insert
与select
的比率是 < 而忽略它。 1.在这种情况下,客户关心下订单需要多长时间。