主键是约束+索引的组合体,强制非空唯一、每表仅一个、作为聚簇索引和外键基础;唯一索引仅保证值唯一(允一个null)、可多建、属二级索引、不支持外键引用。

MySQL 中唯一索引和主键看似功能相似,其实有本质区别:主键是约束 + 索引的组合体,而唯一索引只是索引类型之一;主键天然承担行定位、外键引用、聚簇组织等角色,唯一索引只负责保证字段值不重复(允许一个 NULL)。
核心约束规则不同
主键强制非空且唯一,一个表只能有一个;唯一索引只要求值唯一,但允许出现 一个 NULL 值,且一张表可建多个。比如用户表中,id 设为主键,email 加唯一索引——这样既保证每行有唯一标识,又防止邮箱重复注册,同时允许部分用户暂未填写邮箱(存为 NULL)。
底层存储与查询效率差异
在 InnoDB 中,主键索引就是聚簇索引,叶子节点直接存整行数据;唯一索引属于二级索引,叶子节点只存主键值。这意味着:
- 通过主键查数据只需一次 B+ 树查找
- 通过唯一索引查数据需先查二级索引得主键,再回表查完整行(二次查找)
- 范围查询或排序时,主键索引通常更高效,尤其涉及全行读取场景
业务语义与扩展能力不同
主键具有明确的业务含义:它是整张表的“身份证”,可被其他表用作外键引用;唯一索引没有这种关联能力,它只是辅助校验手段。例如订单表的 order_no 可设为唯一索引(确保单号不重复),但若要被退款表引用为外键,则必须是主键或至少是带外键约束的列——而这在 MySQL 中仅支持主键或含 NOT NULL 的唯一索引(且需显式定义约束)。
创建与修改灵活性不同
主键一旦设定,修改成本高(常需重建表);唯一索引可随时增删,对线上 DML 影响较小。另外,主键自动隐式创建唯一索引,但反过来,给某列加了唯一索引,并不会让它变成主键——也不会获得主键的聚簇特性或外键资格。










