在 MySQL 中,主键(Primary Key) 和 唯一键(Unique Key) 都是用来确保表中数据的唯一性的约束,但是它们之间有一些关键的区别。以下是它们的详细区别:
1. 定义和功能
-
主键(Primary Key):
- 主键用于唯一标识表中的每一行数据。每个表只能有一个主键,主键中的每一列必须是唯一的,并且不允许包含
NULL
值。 - 主键是 表的唯一标识,在没有主键时,MySQL 会自动为每一行分配一个隐藏的主键。
- 主键用于唯一标识表中的每一行数据。每个表只能有一个主键,主键中的每一列必须是唯一的,并且不允许包含
-
唯一键(Unique Key):
- 唯一键用于确保表中的某列(或一组列)值的唯一性,但与主键不同的是,唯一键列可以包含
NULL
值(在 MySQL 中,多个NULL
值是允许的,多个NULL
被认为是不同的)。 - 一个表可以有多个唯一键约束,即同一个表中可以有多个唯一键。
- 唯一键用于确保表中的某列(或一组列)值的唯一性,但与主键不同的是,唯一键列可以包含
2. 约束数量
- 主键:
- 一个表 只能有一个主键,因为主键的目的是唯一地标识每一行数据,只有一个标识符。
- 唯一键:
- 一个表可以有 多个唯一键,每个唯一键都保证相应列(或列组合)的值唯一。
3. NULL 值的处理
- 主键:
- 不允许 NULL 值,因为主键的主要目的是唯一标识记录。如果主键列允许
NULL
,则无法唯一标识记录。
- 不允许 NULL 值,因为主键的主要目的是唯一标识记录。如果主键列允许
- 唯一键:
- 允许 NULL 值,并且可以在唯一键列中插入多个
NULL
值。在 MySQL 中,多个NULL
值被认为是不同的,因此允许多个NULL
值存在。
- 允许 NULL 值,并且可以在唯一键列中插入多个
4. 索引类型
- 主键:
- 主键是 聚簇索引(Clustered Index),这意味着数据行本身按照主键的顺序存储在磁盘上。主键索引不仅确保数据唯一性,还决定了数据存储的物理顺序。
- 唯一键:
- 唯一键是 非聚簇索引(Non-Clustered Index),意味着唯一键的索引存储在独立的结构中,数据行的物理顺序不依赖于唯一键。唯一键确保索引列的唯一性,但数据本身并不会按照唯一键的顺序存储。
5. 默认行为
- 主键:
- 主键约束会隐式地创建一个 唯一索引,保证主键列的唯一性,同时也会影响数据的存储结构。
- 唯一键:
- 唯一键约束会显式地创建一个 唯一索引,用来确保指定列的值唯一。
6. 使用场景
- 主键:
- 主键通常用于 唯一标识表中的每一行数据,例如在用户表中,用户的
ID
字段通常被设为主键,因为每个用户有一个唯一的标识符。
- 主键通常用于 唯一标识表中的每一行数据,例如在用户表中,用户的
- 唯一键:
- 唯一键适用于需要确保某些列的值唯一,但不一定是表中唯一标识符的场景。例如,一个电子邮件地址在某个系统中必须唯一,但它不一定是该表的主键。
7. 示例
1. 创建主键
CREATE TABLE users (
user_id INT NOT NULL,
username VARCHAR(50) NOT NULL,
email VARCHAR(100),
PRIMARY KEY (user_id)
);
在这个例子中,user_id
被设为主键,表示每个用户都可以通过 user_id
唯一标识。user_id
列不允许为 NULL
,并且每个 user_id
都必须唯一。
2. 创建唯一键
CREATE TABLE users (
user_id INT NOT NULL,
username VARCHAR(50) NOT NULL,
email VARCHAR(100),
UNIQUE (email)
);
在这个例子中,email
列被设为唯一键,确保每个用户的电子邮件地址唯一。尽管 email
必须唯一,但它允许包含 NULL
值,因为唯一键允许 NULL
,并且多个 NULL
值不会违反唯一性约束。
总结
特性 | 主键(Primary Key) | 唯一键(Unique Key) |
---|---|---|
约束数量 | 一个表只能有一个主键 | 一个表可以有多个唯一键 |
NULL 允许 | 不允许 NULL 值 | 允许 NULL 值(多个 NULL 被视为不同的值) |
索引类型 | 聚簇索引(Clustered Index) | 非聚簇索引(Non-Clustered Index) |
数据存储 | 数据行按主键顺序存储 | 数据行的顺序不依赖于唯一键 |
目的 | 唯一标识每一行记录,通常是表的主标识符 | 确保某一列(或列组合)的值唯一 |
总之,主键 和 唯一键 都是用来确保数据的唯一性的,但主键是表的唯一标识符,并且不允许 NULL
值,而唯一键则允许多个 NULL
值,并且一个表可以有多个唯一键。