候选键和主键有啥区别?
Posted
技术标签:
【中文标题】候选键和主键有啥区别?【英文标题】:What is the difference between a candidate key and a primary key?候选键和主键有什么区别? 【发布时间】:2012-09-30 13:42:39 【问题描述】:主键是为给定表选择的候选键吗?
【问题讨论】:
CK 和 PK 是关系数据库术语,在 SQL 中具有不同的含义。 What to do with null values when modeling and normalizing? 【参考方案1】:Candidate Key
– 候选键可以是任何列或列的组合,可以有资格作为数据库中的唯一键。一张表中可以有多个候选键。每个候选键都可以作为主键。
Primary Key
– 主键是唯一标识记录的列或列组合。主键只能有一个候选键。
More on this link with example
【讨论】:
CK 是一组唯一的列并且不包含更小的唯一列集。 SQL PK/UNIQE 声明实际上声明了一个超键。【参考方案2】:就目前而言,吴宇森的回答是正确的。以下是一些额外的要点。
主键始终是候选键之一。很多时候,它是唯一的候选者。
没有候选键的表不代表关系。如果您使用关系模型来帮助您构建一个好的数据库,那么您设计的每个表都将至少有一个候选键。
如果没有主键的概念,关系模型将是完整的。它不在关系模型的原始表示中。实际上,在没有声明主键的情况下使用外键引用会导致混乱。这可能是一个逻辑上正确的混乱,但它仍然是一个混乱。声明主键可以让 DBMS 帮助您执行数据规则。大多数情况下,让 DBMS 帮助您执行数据规则是一件好事,而且物有所值。
一些数据库设计者和一些用户对于主键是标识表中的行(记录)还是标识表所代表的主题中的实体实例存在一些心理混淆。在理想的世界中,它应该两者兼而有之,并且实体表中的行与相应实体的实例之间应该存在一对一的对应关系。
在现实世界中,事情变得一团糟。有人两次输入同一个新员工,员工最终有两个 id。有人被录用,但数据输入在某些手动过程中漏掉了,员工没有得到身份证,直到遗漏得到纠正。一个在第一次出现问题时不会崩溃的数据库比一个数据库更健壮。
【讨论】:
我完全支持你,直到你似乎在你说“行之间应该有一对一的对应关系”时建议使用真实世界的值作为主键在实体表和相应实体的实例中”。我强烈建议不要这样做,因为总是有你从未考虑过的例外的可能性。例如,数据库设计人员可能会认为“我将使用一个人的名字作为主键”,然后一个人结婚或通过契约投票更改他们的名字。或者设计师使用汽车注册号作为 PK,然后有人得到一个个性化的注册。等等等等 我不建议使用自然键。那是一个单独的话题。我的建议是在主键的值和实体的实例之间应该存在一对一的对应关系。例如,这可能会被重复的数据输入搞砸。【参考方案3】:主键 -> 可以唯一标识表中记录的任何列或列集都是主键。 (表中只能有一个主键)
候选键 ->任何候选成为主键的列或列集都是候选键。 (表中可以有一个或多个候选键,如果只有一个候选键,可以选择作为主键)
【讨论】:
-1 所有候选键也具有其属性值“可以唯一标识表中的记录”的属性。事实上,他们将正是这样做的。所以这不是区别。 @erwinsmout “成为主键的候选人”意味着他们可以唯一标识一条记录。在候选键中选择主键。我不太确定你的意思 你认为两者有区别还是没有区别? @ErwinSmout,我想我明白了。表中只能有一个主键,而表中可以有一个或多个候选键。我已经编辑了我的答案以反映这一点。感谢您指出。考虑到它是主键定义的一部分,我忽略了它,但是是的,它使答案更加清晰 出于好奇,表是否可能没有候选键,例如如果有重复记录?【参考方案4】:没有区别。主键是候选键。按照惯例,通常选择关系中的一个候选键作为“主”键,但该选择本质上是任意的,并且对于数据库用户/设计人员/开发人员来说是一个方便的问题。它不会使“主”键与任何其他候选键根本不同。
【讨论】:
【参考方案5】:主键是一种特殊的索引:
there can be only one;
it cannot be nullable
it must be unique.
候选键是从一组超级键中选择出来的,我们在选择候选键时唯一要注意的是:它不应该有任何多余的属性。
Employee 表示例: 员工 ( 员工ID, 全名, 社会保障号, 部门编号 )
候选键:是表中符合所有行唯一性的单独列。在 Employee 表中,EmployeeID 和 SSN 是候选键。
主键:是您选择在表中保持唯一性的列。在 Employee 表中,您可以选择 EmployeeID 或 SSN 列,EmployeeID 是更好的选择,因为 SSN 是一个安全值。
备用键:主列以外的候选列,例如如果 EmployeeID 是 PK,则 SSN 将是备用键。
超级键:如果您将任何其他列/属性添加到主键,则它会成为超级键,例如 EmployeeID + FullName,是超级键。
复合键:如果表没有符合候选键的单列,则必须选择 2 列或更多列以使行唯一。就像没有 EmployeeID 或 SSN 列一样,您可以将 FullName + DateOfBirth 作为复合主键。但是,重复行的可能性很小。
【讨论】:
【参考方案6】:一个表可以有这么多列可以唯一标识一行。这些列被称为候选键,但主键应该是其中之一,因为一个主键足以用于一张表。所以主键的选择在众多候选键中很重要。这就是主要区别。
【讨论】:
【参考方案7】:想象一张带有整数主键的车辆表。
注册号将是候选键。
在现实世界中,注册号会发生变化,因此在一定程度上取决于可能有资格成为候选键的情况。
【讨论】:
【参考方案8】:主键 -> 任何可以唯一标识表中记录的列或列集都是主键。 (表中只能有一个主键)和 候选键-> 与主键相同,但数据库管理员预期选择的主键例如(主键大小最小的候选键)
【讨论】:
您认为这增加了许多高度赞成和旧答案的什么,以使每个投票箭头鼠标悬停文本“有用”?另外,您的CK句子不清楚。还有,你的PK语句不清楚。 PS 在 SQL 中:CK 是一组没有空值的唯一列。 PK 是被选为 PK 的 CK 之一。在关系模型理论中:没有空值。超级键是一组唯一的列。 CK 是一个不包含更小的超级密钥的超级密钥。 PK 是被选为 PK 的 CK 之一。所以这里已经有很多内容很差,文笔很差的回答帖子。 我相信@Ahmed Nasr Elhariri 有一个很好的观点 - “与主键相同,但主键由数据库管理员选择”......检查 nvogel 的答案以将它们联系在一起。 @Fact 所有这一切都增加了 nvogel 的答案是错误的:“主键是最小的候选键大小”。【参考方案9】:主键是表中唯一标识该表中行的一列(或多列)。
CUSTOMERS
CustomerNo FirstName LastName
1 Sally Thompson
2 Sally Henderson
3 Harry Henderson
4 Sandra Wellington
例如上表中,CustomerNo 是主键。
放置在主键列中的值对于每一行必须是唯一的:不能容忍重复。另外,主键列中不允许有空值。
那么,在告诉您可以使用一列或多列作为主键之后,您如何决定选择哪些列(以及多少列)?
嗯,有时建议或必须使用多个列。但是,如果您看不到使用多个列的直接原因,请使用一个。这不是一个绝对的规则,它只是一个建议。但是,由单列组成的主键通常更容易维护,运行速度更快。这意味着,如果您查询数据库,如果表具有单列主键,您通常会更快地得到答案。
下一个问题——你应该选择哪一列?选择一列作为主键的最简单方法(以及一种合理常用的方法)是让数据库本身自动为每一行分配一个唯一编号。
在员工表中,显然任何像 FirstName 这样的列都是一个糟糕的选择,因为您无法控制员工的名字。主键通常只有一个选择,如上例所示。但是,如果有多个,则可以将它们描述为“候选键”——名称反映了它们是主键负责工作的候选者。
【讨论】:
如果您“维护”主键,那么您将面临一个痛苦的世界。您的示例无法解释为什么FirstName
、LastName
的多列键有问题。此外,CustomerNo
甚至是 in 数据库的原因是(可能)“客户”实体上没有自然候选键 - 也就是说,您没有候选键 完全,直到它被添加;如果有人在设计一张桌子,他们一开始并没有代理键,而是根据需要添加的。【参考方案10】:
如果超键是一个大集合,则候选键是大集合中的一些较小集合,主键是候选键集中的任何一个元素(一次一个或一个表)。
【讨论】:
【参考方案11】:首先你必须知道什么是行列式? 行列式是用于确定同一个表中的另一个属性的属性。 所以行列式必须是候选键。你可以有多个决定因素。 但是主键是用来确定整条记录的,你只能有一个主键。 主键和候选键都可以包含一个或多个属性
【讨论】:
以上是关于候选键和主键有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
超键(super key)、候选键(candidate key)和主键(primary key) 外键(foreign key)的区别