今天我们一起来理一理数据库中保证数据 唯一性 的三种机制,它们分别是 主键约束(Primary Key Constraint)、唯一性约束(Unique Constraint)、唯一性索引(Unique Index)。
一、主键约束(Primary Key Constraint)
1、定义:主键约束是表中用于 唯一标识每条记录 的约束,通过一列或多列(复合主键)的组合,确保表中不存在两条完全相同的记录,且 不允许空值(NULL)。
2、核心特性:
- 唯一性:主键列(或列组合)的值必须唯一,不能重复。
- 非空性:主键列的值绝对不允许为 NULL(所有列都不能空)。
- 标识性:是表的 “唯一身份证”,用于明确区分每条记录,通常作为其他表的外键引用的目标(如订单表的user_id引用用户表的主键id)。
- 自动关联索引:数据库会自动为 – primary key 创建唯一索引(多数数据库默认是聚集索引,如 SQL Server;Oracle 默认是非聚集索引),以高效维护唯一性。关于 聚集索引与非聚集索引,大家可以看下这篇文章 聚集索引与非聚集索引的区别。
3、示例:
CREATE TABLE user (
id INT PRIMARY KEY, -- 主键
name VARCHAR(50)
);
二、唯一性约束(Unique Constraint)
1、定义:唯一性约束是用于保证表中 指定列(或列组合)的值在全表范围内唯一 的约束,主要用于业务逻辑上的唯一性要求(比如 “身份证号不重复”)。
2、核心特性:
- 唯一性:约束列(或列组合)的值必须唯一,不能重复。
- 允许空值:允许列值为 NULL,且 允许多个 NULL(因为 NULL 不等于任何值,包括自身,所以多个 NULL 不违反唯一性)。
- 业务性:不用于标识记录,仅用于保证业务规则(比如 “一个用户只能有一个身份证号”)。
- 自动关联索引:数据库会 自动为 unique constraint 创建唯一索引(默认是非聚集索引),以高效检查唯一性。
3、示例:
CREATE TABLE user (
id INT PRIMARY KEY, -- 主键
id_card VARCHAR(100) UNIQUE -- 唯一约束
);
三、唯一性索引(Unique Index)
1、定义:唯一性索引是一种 物理存储结构,通过对指定列(或列组合)创建索引,强制该列值唯一,同时 加速基于该列的查询(如WHERE
条件过滤、JOIN
关联)。
2、核心特性:
- 唯一性:索引列(或列组合)的值必须唯一,不能重复。
- 允许空值:同唯一性约束,允许列值为 NULL,且允许多个 NULL。
- 性能导向:核心作用是 优化查询速度(减少数据扫描范围),”唯一性” 是附加特性。
- 手动创建:需要显式通过
CREATE UNIQUE INDEX
语句创建,不依赖约束存在。
3、示例:
CREATE UNIQUE INDEX idx_id_card ON user(id_card); -- 唯一索引
对比表格
维度 | 主键约束(Primary Key) | 唯一性约束(Unique Constraint) | 唯一性索引(Unique Index) |
---|---|---|---|
约束类型 | 逻辑约束(数据完整性规则) | 逻辑约束(数据完整性规则) | 物理结构(索引,优化查询) |
空值允许 | 不允许任何列为 NULL | 允许列值为 NULL(允许多个) | 允许列值为 NULL(允许多个) |
数量限制 | 一个表只能有 1 个主键(可复合) | 一个表可以有多个唯一性约束 | 一个表可以有多个唯一性索引 |
与索引的关系 | 自动创建唯一索引(不可单独删除) | 自动创建唯一索引(不可单独删除) | 本身就是索引(可单独创建 / 删除) |
作用核心 | 标识记录(表的 “身份证”) | 保证业务唯一性(如邮箱不重复) | 提升查询性能(附带唯一性) |
外键引用目标 | 可被其他表的外键引用 | 通常不被外键引用(语义不适合) | 不能被外键引用(不是约束) |
删除影响 | 删除主键约束,自动索引会被删除 | 删除唯一性约束,自动索引会被删除 | 删除索引,不影响约束(若存在) |
总结
- 主键约束:唯一标识记录,非空,表中唯一,是表的 “核心身份标识”。
- 唯一性约束:保证业务字段唯一,允许空,可多个,是 “业务规则的守护者”。
- 唯一性索引:优化查询速度,附带唯一性,可多个,是 “性能优化工具”。
世上没有完美的人,也没有完美的事。– 烟沙九洲