主键和代理键有什么区别?

64

我进行了大量的谷歌搜索,但没有找到确切的简单明了的答案,并带有示例。

如果有示例的话,将更加有帮助。


1
从我理解的角度来看,如果在一个表中没有我们确信会始终是唯一且非空的属性可以作为该表的主键,那么我们将使用人工创建(不派生自该表)的属性(通常是自增ID)作为该表的主键。该人工创建的列被称为代理键,因为它的目的是作为主键而不是从表中派生而来。 - aMighty
一个主键是一列或一组列,用于唯一标识数据库表中的每个记录。它可以由应用程序或用户提供,并且通常是表中的某些数据的逻辑标识符。另一方面,代理键是任何用于标识表中记录的键,不是从表中的现有数据派生的。代理可以是候选键。 - Channa
6个回答

98

主键是您选择的在表中唯一标识记录的最佳键。所有表都应该有一个主键,因为如果您需要更新或删除记录,您需要知道如何唯一地标识它。

代理键是人工生成的键。当您的记录基本上没有自然键时(例如表,因为可能出生于同一日期的两个人具有相同的姓名,或记录在日志中,因为可能会发生两个事件,使得它们具有相同的时间戳)。通常,您会将它们实现为自动递增字段中的整数,或者作为为每个记录自动生成的GUID。ID号几乎总是代理键。

与主键不同,不是所有表都需要代理键。如果您有一个列出美国州份的表,则实际上不需要其ID编号。您可以使用州缩写作为主键代码。

代理键的主要优点是易于确保唯一性。其主要缺点是它们没有任何意义。例如,“28”不表示威斯康星州,但是当您在地址表的州/省列中看到“WI”时,您无需查找状态表即可知道所讨论的州/省是哪个。


我认为主要的缺点是有时候人们使用自动生成的键(通常在没有自然键存在时使用整数代替自然键),他们经常忘记在未选择为PK的自然键上放置唯一索引。这通常会导致重复项进入系统,从而可能创建问题。 自动生成键的两个主要优点是它们通常增加了连接的性能(如果是整数而不是GUIDS),并且它们防止在自然键更改时大量更新许多子记录。 - HLGEM
@HLGEM 当然,我会买那些的。我认为我关注缺乏意义是因为我刚刚在超规范化系统中工作,基本上每个字段都是它自己的表。这使得无法确定数据输入错误发生的位置,并且很难应用业务规则来定位问题。 - Bacon Bits
我喜欢规范化,但你确实可以过度追求。 - HLGEM
@BaconBits:我的所有数据库都不允许出现空值。因为外连接会生成空值,所以我在任何数据库代码(视图等)中都不使用它们。我应用“封闭世界假设”即表中的一行表示真实存在,而没有这样的行则表示不存在。不用说,我使用一阶逻辑,并拒绝 SQL 的三值逻辑,因为它过于复杂、不必要且实现不一致。你的所有预测(业务规则验证、连接类型、性能等)都是错误的。 - onedaywhen
@BaconBits "并不是所有的表都需要代理键"," '28' 代表威斯康星州没有任何意义" - 我同意这两个说法;你在这里说的其他一切都是推测或无意义的。 - onedaywhen
显示剩余6条评论

8

代理键是一种虚构的值,其唯一目的是标识行。通常,这由自动递增的ID表示。

示例代码:

CREATE TABLE Example
(
    SurrogateKey INT IDENTITY(1,1) -- A surrogate key that increments automatically
)

主键是表的标识列或一组标识列。可以是 代理键 或任何其他唯一的列组合(例如复合键)。必须对于任何行都是唯一的,且不能为NULL

示例代码:

CREATE TABLE Example
(
    PrimaryKey INT PRIMARY KEY -- A primary key is just an unique identifier
)

3

所有键都是用作它们所标识的事物的代理的标识符。E.F.Codd解释了系统分配代理的概念如下[1]:

数据库用户可能会导致系统生成或删除代理,但他们无法控制其值,也不会将其值显示给他们。

这就是所谓的代理键。然而,定义立即存在问题,因为Codd假设DBMS将提供此功能。通常,DBMS没有此类功能。由于某些明显的原因,键通常对至少一些DBMS用户可见。因此,代理的概念在使用中略有变化。该术语通常在数据管理专业中用于表示在业务领域中未公开使用作为标识符的键。请注意,这与密钥的生成方式或被认为是多么“人工”完全无关。所有密钥都由人类或机器发明的符号组成。因此,术语代理的唯一可能意义与密钥的使用方式有关,而不是与其创建方式或值有关。

[1] 扩展数据库关系模型以捕获更多含义,E.F.Codd,1979年


1

1

0

我认为Michelle Poolet用非常清晰的方式描述了它:

代理键是一种人工生成的值,通常是系统管理的递增计数器,其值可以从1到n,其中n表示表的最大行数。在SQL Server中,您可以通过将标识属性分配给具有数字数据类型的列来创建代理键。

http://sqlmag.com/business-intelligence/surrogate-key-vs-natural-key

当您使用具有标识列的复合键进行更改时,使用代理键通常会有所帮助。


3
我给-1分是因为它没有解释其中的区别。 - TomTom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接