NULL 值(隐式 NOT NULL 约束)。ROW_ID作为聚集索引。NULL 值(MySQL特性,与SQL标准不同,其他数据库如Oracle/SQL Server仅允许单个NULL)。email + phone + national_id)。UNIQUE NOT NULL索引作为聚集索引。ROW_ID竞争(如组提交时影响InnoDB事务性能)。BIGINT UNSIGNED AUTO_INCREMENT,无业务意义且紧凑。| 特性 | 主键索引 | 唯一索引 |
|---|---|---|
| NULL 允许 | ❌ 绝对禁止 | ✅ 允许多个NULL(MySQL特性) |
| 数量限制 | 每表仅1个 | 可创建多个 |
| 索引类型 | 必定为聚集索引 | 默认为非聚集索引 |
| 是否强制 | 推荐显式定义,否则自动生成隐藏主键 | 完全可选,按需添加 |
| 外键关联 | 默认被引用 | 可显式指定为外键引用目标 |
| 存储内容 | 包含完整数据行(聚集索引) | 存储索引列+主键值(需回表查询) |
| 典型用例 | 数据表核心标识(如user_id) |
业务防重(如email、order_no) |
主键设计原则
唯一索引陷阱
WHERE email = NULL 无法命中索引,需用IS NULL。UNIQUE(a,b)可支持a=?查询,但无法单独用b=?。性能调优
INCLUDE或联合索引减少回表,如SELECT user_id FROM users WHERE email='xxx'可利用唯一索引直接返回。-- 显式定义自增主键
CREATE TABLE users (
user_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 聚集索引
email VARCHAR(255) NOT NULL,
phone VARCHAR(20),
UNIQUE KEY uk_email (email), -- 唯一索引
UNIQUE KEY uk_phone (phone) -- 允许phone为NULL且存在多条NULL
);
-- 外键引用唯一索引
CREATE TABLE orders (
order_id VARCHAR(32) PRIMARY KEY, -- 自然主键(需确保绝对唯一)
user_id BIGINT UNSIGNED,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
最终结论:主键是数据组织的基石,唯一索引是业务规则的守护者。设计时应严格区分两者用途,主键追求极致稳定和高效,唯一索引则需贴合业务防重需求。