主键和唯一键的区别

301
我正在使用 MySQL 数据库。 在哪些情况下应该创建唯一键或主键?

14
关于空值性(nullability)的一个好方法是区分它们: 主键 = 唯一键 + 非空约束(Not Null CONSTRAINT) - KNU
2
请查看http://dba.stackexchange.com/questions/15572/differences-between-unique-key-and-primary-key/149580#149580。以及https://dev59.com/O3M_5IYBdhLWcg3wZSE6#19345477。 - LCJ
15个回答

283

主键(Primary Key):

  • 一张表中只能有一个主键约束
  • 在某些DBMS中,它不能为NULL - 例如,MySQL会添加NOT NULL
  • 主键是记录的唯一键标识符

唯一键(Unique Key):

  • 一张表中可以有多个唯一键
  • 唯一键可以有NULL
  • 它可以是候选键
  • 唯一键可以为NULL;多行可以有相同的NULL值,因此可能不被认为是“唯一”的。

23
还想补充一点,主键可以在多列上创建,例如主键(CustomerID,ProductID)。这被称为组合主键。这是为了澄清第一个观点,因为新来者可能会将其理解为(读取一个键=>一个列): ) - ken
2
“可以成为候选键”是什么意思? - user4920811
1
“只允许单个空值” - 这不是真的,至少对于MySQL来说不是。 - Jānis Elmeris
74
这句话的意思是:独特键(Unique key)可以为空值(null),并且不一定是唯一的。 - Pratik Joshi
21
他可能是指在唯一键上除了空值以外还可以有多个行�� - John
显示剩余9条评论

91

唯一键(UK):它是一列或一组列,可以在行中标识出唯一性。

主键(PK):它也是一列或一组列,可以在行中标识出唯一性。

因此,主键只是唯一键的另一个名称,但在SQL Server中的默认实现对主键和唯一键有所不同。

默认情况下:

  1. PK创建聚集索引,而UK创建非聚集索引。
  2. PK不能为空,但UK允许空值(注意:默认情况下)。
  3. 一个表只能有一个主键,但可以有多个唯一键。
  4. 您可以根据需要覆盖默认实现。

决定创建UK还是PK真的取决于您的目的。它遵循一个类比:“如果有一个由三个人组成的团队,那么他们都是同级别的,但其中会有一个人是同辈中的一对:PK和UK有类似的关系。”我建议阅读这篇文章:http://tsqltips.blogspot.com/2012/06/difference-between-unique-key-and.html。作者给出的例子可能不太适合,但请尽量了解整体思路。


阅读了大约10个网页,它们都说PK可以包含多列。那么在一个表上怎么可能只有一个且唯一的PK呢? - user6192706
@android 如果一个PK有多列,那么它在唯一性方面就像单列一样。至少在PostgreSQL中,这意味着会向表中添加一个新列(默认名称为“[table_name]_pkey”)(我听说这被称为代理键)。来源:http://www.postgresqltutorial.com/postgresql-primary-key/ 我对这些都很陌生,所以我希望更有经验的发帖人能指出我错过的细节。 - Poik
好的,这不是一个列。我读错了。它是一个约束,而不是一个列。仍然有聚集索引,但它是在两个列上而不是一个上。并且其中每个列本身都不是主键,而整个集合是一个主键。因此,在这些情况下没有多个PK。 - Poik

51

对于一个组织或企业而言,存在许多物理实体(如人员、资源、机器等)和虚拟实体(它们的任务、交易、活动等)。通常,业务需要记录和处理这些业务实体的信息。这些业务实体通过一个键在整个业务域内进行标识。

根据关系型数据库管理系统(RDBMS)的角度来看,键(也称为候选键)是唯一标识实体的一个值或一组值。

对于一个数据库表,存在许多键并且可能符合主键的条件。因此,所有键,包括主键、唯一键等,统称为候选键。然而,数据库管理员从候选键中选择一个用于搜索记录的键称为主键。

主键与唯一键的区别:

1. 行为:主键用于标识表中的一行(记录),而唯一键用于防止列中出现重复值(除了空条目)。

2. 索引:默认情况下,如果不存在,则SQL引擎在主键上创建聚集索引,而在唯一键上创建非聚集索引。

3. 可空性:主键不包括空值,而唯一键可以包括。

4. 存在性:一张表最多只能有一个主键,但可以有多个唯一键。

5. 可修改性:无法更改或删除主键值,但可以更改唯一键值。

更多信息和示例请参考:

http://dotnetauthorities.blogspot.in/2013/11/Microsoft-SQL-Server-Training-Online-Learning-Classes-Integrity-Constraints-PrimaryKey-Unique-Key_27.html


10
您在第五点中提到无法更改或删除主要值,但是我们可以使用更新语句来更改表中的主要值。 - Kapil
4
@Kapil 这样做完全违背了使用主键的初衷。 - Gokigooooks
4
聚集索引:行在磁盘上的物理存储顺序与索引相同。 - Duy Đặng

27

主键必须是唯一的。

唯一键不一定是主键 - 请参见候选键

也就是说,在一个表上可能有多个列的组合可以唯一地标识一行 - 只能选择其中一个作为主键。其他的虽然唯一,但都是候选键。


21
主键 唯一键
主键不能接受NULL 唯一键可以接受NULL值,因此在唯一性方面存在问题
主键不能包含重复的值 唯一键也不能包含重复的值
一个表只能有一个主键 一个表可以有多个唯一键
我们可以从一个或多个表字段创建主键 我们也可以从一个或多个表字段创建唯一键
默认情况下,主键创建一个聚集索引 默认情况下,唯一键创建一个非聚集唯一索引
主键用于标识表中的每条记录 它防止在列中存储重复的条目

是的,“每列只有一个空值”是SQL Server但不是标准SQL。PS我转换为Markdown表格格式。 - philipxy

17

主键具有标识数据库行的语义。因此,对于给定的表,只能有一个主键,而可以有许多唯一键。

同样基于这个原因,在Oracle中,主键不能为NULL(其他数据库不确定)。

由于它标识行,因此它永远不应该改变。更改主键将导致严重痛苦和可能是永恒的刑罚。

因此,在大多数情况下,您需要一些人工 ID 用作主键,该 ID 仅用于标识表中的单个行。

另一方面,唯一键可以随意更改。


23
+1 提到永恒地狱的风险。是时候将神学引入关系数据库理论中了。 - Neville Kuyt
SQL Server中PK不能为空。 - mrd3650

9

主键是一种唯一的键。

每个表最多只能有一个主键,但可以有多个唯一键。主键用于唯一标识表中的行。主键不能为NULL,因为NULL不是一个值。


9
我知道这个问题已经几年了,但我想提供一个解答,以解释为什么而不是如何。
主键的目的:唯一标识数据库中的一行=> 一行代表表建模的实体类型的单个实例。主键强制执行实体完整性,也称为实体完整性。主键将是聚集索引,即它定义了数据在表中物理存储的顺序。
唯一键的目的:好的,有了主键,我们有一种方法来唯一标识一行。但是我有一个业务需求,另一列/一组列应具有唯一值。从技术上讲,鉴于这个列是唯一的,它可以成为强制实体完整性的候选项。但是据我们所知,这个列可能包含来自外部组织的数据,我可能对其唯一性存在疑问。我不能信任它提供实体完整性。我只是将其设置为唯一键以满足我的业务要求。
就是这样!

8
  • 假设表名为employe。
  • 主键
  • 主键不能接受空值,它强制确保列的唯一性。一个表中只能有一个主键。
  • 唯一键
  • 唯一键可以接受空值,也强制确保列的唯一性。你可能会问,如果唯一键包含空值,那么它如何保证唯一性呢?虽然它可以接受空值,但是它还是强制确保列的唯一性。请看下面的图片,这里Emp_ID是主键,Citizen ID是唯一键。希望您明白了。我们可以在一个表中使用多个唯一键。 enter image description here

1
我们不能在唯一键中插入超过一个空值,并且它也不允许重复。 - Masum
@mahedi-hasan 唯一键列不应该只有一个NULL值吗?公民身份证的最后两行为什么是NULL?我有什么遗漏的吗? - supernova
刚刚得到了对我上面评论的答案。看起来MySQL也允许在唯一性约束中有多个NULL,所以@Mahedi_Hasan可能使用了MySQL。https://dev59.com/Q3A65IYBdhLWcg3wogOe#3712251 - supernova

1

唯一键:

当您需要提供唯一值时,应使用它。在唯一键的情况下,它表示空值也是允许的。唯一键是那些在该列中唯一且不相似的键,例如您的宠物名字。它可能什么都没有,比如null,如果您是在数据库的上下文中提问,那么必须注意每个null在数据库中都不同。除了SQL Server,其中null=null为真


主键:当您需要唯一标识一个行时,应使用它。主键是每个数据库约束中唯一的关键字,不允许其中为空。因此,您可能已经看到数据库中有一个自动增量的列,它是表的主键。此外,它可以用作另一个表中的外键,例如订单表中的orderId、账单表中的billId。
现在回到使用情况:
1) 在另一个表中使用作为外键创建关系的表中不能为null的列上的主键
2) 在表中使用唯一键,该键不会影响整个数据库或表,例如餐厅中的小吃,可能不会点小吃。

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