在连接表中,我应该使用主键和唯一约束,还是使用复合/复合键



我已经通读了很多似乎会使这成为一个重复问题的内容。但读完所有这些让我感到不确定。我希望根据下面的绝对示例得到一个答案,因为许多问题/答案会在辩论中反复出现。

如果我有:

dbo.Book
--------
BookID PK int identity(1,1)
dbo.Author
----------
AuthorID PK int identity(1,1)

现在,对于一个简单的接线表,我有两个选择:

dbo.BookAuthor
--------------
BookID CPK and FK
AuthorID CPK and FK

上面的内容将是两个FK上的复合/复合键,以及为两列设置FK关系-也可以在删除时使用Cascade。

dbo.BookAuthor
--------------
RecordID PK int identity(1,1)
BookID FK
AuthorID FK

BookID和AuthorID上的外键关系,以及删除时的Cascade。还对BookID和AuthorID设置一个唯一的约束。

我正在寻找一个简单的答案,解释为什么在上面的特定例子中,一种方法比另一种更好。我读到的答案非常详细,我正要确定一个复合键,但后来看了一段视频,这个例子使用了一个"身份"列,就像我的第一个例子一样。

这个话题似乎有点一分为二,但我的直觉告诉我,我应该只使用复合键。

什么查询更高效?似乎有一个PK身份列,同时在这两列上设置一个唯一的约束,并且FK关系的成本会更高,即使有点高。

这是我在大学时的数据库课程中一直记得的东西。我们正在复习课本上关于";实体设计;它在谈论接线桌。。。我们称之为交集表或交集关系。事实上,那天我在课堂上专心听讲。这位教授说,根据他的经验,多对多的连接表几乎总是表明有一个身份不明的缺失实体这些实体几乎总是以自己的数据结束。

我们给出了一个StudentCourse实体的例子。对于一个学生来说,你需要把这两者结合起来。因此,您实际拥有的是一个新实体:Enrollment。在这种情况下,额外的数据是信用类型(审计与常规)或最终成绩。

直到今天我还记得那个建议。。。但我并不总是遵循它。在这种情况下,我要做的是停止,并确保就这个问题回到利益相关者那里,与他们合作,找出我们在这个路口可能仍然缺少的数据点。如果我们真的找不到任何东西,那么我就用复合键。当我们找到数据时,我们会想到一个更好的名称,它会得到一个代理密钥。

2020年更新
我还保留着课本,令人惊讶的是,它和这个问题在几个小时内就引起了我的注意。因此,对于好奇的人来说,这是本书第7版的第5章第6节:

https://www.amazon.com/Database-Processing-Fundamentals-Design-Implementation-dp-9332549958/dp/9332549958/

作为代理键优点的坚定支持者和倡导者,我对所有键联接表(如第一个示例)都破例。代理密钥的好处之一是,引擎通常针对单个整数字段的连接进行优化,这是默认的也是最常见的情况。

您的第一个提议仍然可以获得这一好处,但在每个索引级别上都有50%的粉丝,从而降低了联接表上索引的总体大小和高度。尽管对于比大型表更小的表来说,这样做的性能优势可能微不足道,但这是最佳实践,而且是免费的。

当我可能选择另一种设计时,如果关系要增加额外的列。在这一点上,它不再是严格意义上的联接表。

我更喜欢第一种设计,使用复合键。即使父表具有标识列,在连接表上具有标识列也不会给您带来优势。您不会使用identity列查询BookAuthor,而是使用BookIDAuthorID进行查询。

此外,添加标识将允许重复的BookID-AuthorID组合,除非您设置了约束。

此外,如果您的主键是(BookID, AuthorID),则需要在AuthorID, BookID)上创建索引。如果你想查询作者写的书,这将有所帮助。

使用复合键也是我的选择。原因如下:

减少存储开销

假设您将使用代理密钥。由于您可能想要查询特定书籍的所有作者,反之亦然,因此您需要以BookId和AuthorId开头的索引。出于性能原因,您应该在两个索引中都包含另一列,以防止聚集键查找。您可能希望将其中一个设置为唯一的,以确保不会向表中添加重复的BookId/AuthorId组合。

因此,最终结果是:

  • 数据存储3次,而不是2次
  • 将验证2个唯一约束,而不是1个

查询连接表引用表

即使您添加了一个类似Contributions (AuthorId, BookId, ...)的表来引用连接表。大多数查询根本不需要触摸连接表。例如:查找特定作者的所有贡献只涉及作者和贡献表。

根据连接表中的数据量,复合密钥最终可能会导致与自动生成的顺序主键相比性能较差。

主键是表的聚集索引,这意味着它决定了磁盘上存储行的顺序。如果主键的值不是按顺序生成的(例如,它是一个由表中的外键组成的复合键,其中的行与连接表的行不按相同的顺序排列,或者它是GUID或其他随机键),则每次向连接表中添加行时,都需要重新排列连接表的列。

您可能应该使用复合/复合键。通过这种方式,你可以完全建立关系——一个作者可以写很多书,一本书可以有多个作者。

最新更新