外键-使用代理键还是自然键链接?


14

对于表之间的外键应该链接到自然键还是代理键,是否存在最佳实践?我真正发现的唯一讨论(除非缺少我的google-fu)是杰克·道格拉斯在这个问题上的答案,他的推理对我来说似乎很合理。我知道有关规则会发生变化的讨论之外,但是在任何情况下都需要考虑这一点。

提出这个问题的主要原因是,我有一个使用带有自然键的FK的遗留应用程序,但是开发者大力推动将其移至OR / M(在我们的例子中为NHibernate),并且一个fork已经产生了一些东西。中断更改,因此我希望使用自然键将它们推回正轨,或者移动旧版应用程序以使用FK的替代键。我的直觉说要恢复原始的FK,但是老实说,我不确定这是否是正确的选择。

我们的大多数表都已经定义了代理键和自然键(尽管有唯一约束和PK),因此在这种情况下,不必添加额外的列对我们来说不是问题。我们正在使用SQL Server 2008,但是我希望这对于任何数据库都足够通用。

Answers:


15

SQL和关系模型都不会受到引用自然键的外键的干扰。实际上,引用自然键通常会大大提高性能。您会惊讶于您所需的信息被完全包含在自然键中的频率。引用该键可将联接换成更宽的表(因此减少了可在一页中存储的行数)。

根据定义,您所需的信息始终完全包含在每个“查找”表的自然键中。(术语查询表是非正式的。在关系模型中,所有表都只是表。美国邮政编码表中的行可能看起来像这样:{AK,阿拉斯加},{AL,阿拉巴马州},{AZ,亚利桑那州} ,等等。大多数人会称其为查找表。)

在大型系统上,查找具有多个候选键的表并不少见。服务于企业的一部分的表引用一个候选键,而服务于企业的另一部分的表引用不同的候选键也很常见。这是关系模型的优势之一,并且是SQL很好地支持的关系模型的一部分。

当您在还具有代理键的表中引用自然键时,将遇到两个问题。

首先,您会让人们感到惊讶。尽管我通常会强烈建议“最不惊奇原则”,但是在这种情况下,我并不介意让人感到惊讶。当问题是开发人员对外键的逻辑使用感到惊讶时,解决方案是教育而不是重新设计。

其次,ORM通常不是围绕关系模型设计的,它们有时体现不反映最佳实践的假设。(实际上,它们的设计似乎常常没有数据库专业人员的输入。)在每个表中都需要一个ID号是这些假设之一。另一个假设ORM应用程序“拥有”数据库。(因此,可以免费创建,删除和重命名表和列。)

我曾在一个数据库系统上工作过,该系统在30年中为至少用两种语言编写的数百个应用程序提供数据。该数据库属于企业,而不属于ORM。

引入重大变化的叉子应该是秀场停止者。

我曾经在一家公司工作过,同时使用自然键和代理键来衡量性能。有一个临界点,代理键开始超过自然键。(假设没有额外的努力来保持自然键性能很高,例如分区,部分索引,基于函数的索引,额外的表空间,使用固态磁盘等。)根据我对该公司的估计,它们将达到大约2045年。与此同时,使用自然键可以获得更好的性能。

其他相关答案:在数据库架构混乱中


5

我支持代理键的主要原因是自然键经常会发生变化,这意味着必须更新所有相关表,这可能会对服务器造成很大的负担。

在过去的30年中,我一直在使用有关许多主题的各种数据库,真正的自然键通常很少。所谓的唯一事物(SSN)并非如此,在特定时间唯一的事物在以后可能变得不唯一,并且诸如电子邮件地址和电话号码之类的事物可能是唯一的,但以后可以将它们重新用于不同的人日期。当然,有些东西根本没有像个人和公司名称那样的唯一标识符。

至于避免使用自然键进行联接。是的,这样可以加快不需要联接的select语句的速度,但是由于int联接通常更快,因此这会导致您仍需要联接的位置变慢。它还可能会减慢插入和删除的速度,并在密钥更改时导致更新性能问题。复杂的查询(无论如何都会比较慢)甚至会更慢。因此,简单的查询速度更快,但报告和复杂的查询以及针对数据库的许多操作则可能较慢。这是一种平衡的行为,根据查询数据库的方式,可能采取一种或多种方法。

因此,没有一个适合所有人的答案。它取决于您的数据库以及如何查询数据库以及存储在其中的信息类型。您可能需要进行一些测试,以找出最适合自己环境的方法。


1
“ ...自然键经常会发生变化...”-那么它们不是很好的键!如果属性经常更改,则不要将其用作键(当然,对于“经常”的各种定义)。费边·帕斯卡 Fabian Pascal)认为选择钥匙有四个标准:熟悉性,不可还原性,稳定性和简单性。有时,为了简化代理密钥,您需要权衡这些。正如HLGEM所说:“因此,没有一个适合所有人的答案”。
Greenstone Walker

1
@GreenstoneWalker,我同意您当时不应该将其作为键,但是通常您没有适合所有四个条件的键,因此必须遵循独特的标准。而且,当唯一性是共存的键时,那么在必须具有联接的情况下,性能甚至可能更大。
HLGEM

-4

如果您不知道答案,请使用代理。这就是原因-如果对业务规则进行假设,并且这些假设是错误的或规则发生更改,那么您的数据就是垃圾。这是一个例子:

人,角色,人角色

当前的业务规则规定一个人具有一个角色。您创建一个链接Person和Role的表,其中PersonRole(PersonName,PersonBirthDate,PersonMotherMaidenName,...,RoleCode)

现在,当您使用自然键时,您将是一个真正的纯粹主义者!但是,如果组织决定某个人现在可以担任多个职务,该怎么办?支持业务需求变化的下游影响是什么?


2
而且代理键没有这些问题吗?请告诉我们如何。
科林·哈特

4
给出的示例似乎没有证明与讨论有关的任何内容。
mustaccio 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.