MySQL唯一索引能否做主键索引

结论先行:

✅ 可以------在没有显式主键的情况下,InnoDB 会优先选择第一个 NOT NULL 的唯一索引作为"聚簇索引(主键)"。

❌ 但不能直接把一个普通唯一索引"变成"主键,需要符合规则。

下面详细说明 👇

一、InnoDB 如何选择主键(非常重要)

InnoDB 的主键本质是 聚簇索引(Clustered Index)。

如果表中 没有定义 PRIMARY KEY,InnoDB 会按以下顺序选择:

✅ 选择顺序

  1. 显式定义的 PRIMARY KEY
  2. 第一个 NOT NULL 的唯一索引
  3. 系统自动生成的隐藏 ROW_ID(6 字节)

📌 唯一索引 ≠ 一定是主键

📌 只有 NOT NULL 的唯一索引才可能成为主键

二、示例说明

✅ 情况 1:唯一索引可充当主键

CREATE TABLE user (

email VARCHAR(100) NOT NULL,

UNIQUE KEY uk_email (email)

);

👉 InnoDB 会:

• 使用 uk_email 作为 聚簇索引

• 等价于主键(但不叫 PRIMARY KEY)

SHOW INDEX FROM user;

你会看到:

• Key_name = uk_email

• Non_unique = 0

• 实际承担主键角色

❌ 情况 2:唯一索引允许 NULL → 不能做主键

CREATE TABLE user (

email VARCHAR(100),

UNIQUE KEY uk_email (email)

);

❌ 因为允许 NULL

❌ InnoDB 不会用它作为主键

✅ 会使用隐藏 ROW_ID

三、能不能"把唯一索引改为主键"?

✅ 正确做法

ALTER TABLE user

ADD PRIMARY KEY (email);

⚠️ 前提条件:

• email 必须是 NOT NULL

• 不能有重复值

❌ 错误理解

-- 这并不会让 uk_email 成为主键

ALTER TABLE user ADD UNIQUE KEY uk_email (email);

👉 它只是唯一索引,不是 PRIMARY KEY。

四、唯一索引"充当主键"的优缺点

✅ 优点

• 省去一个额外的自增 ID

• 减少一次索引查找(覆盖索引更友好)

• 适合 业务主键明确 的场景

❌ 缺点

• 主键更新成本高(InnoDB 会移动行)

• 业务字段变更会影响所有二级索引

• UUID / 字符串做主键会导致页分裂严重

五、强烈推荐的通用设计 ✅

场景 推荐方案

绝大多数业务表 id BIGINT AUTO_INCREMENT PRIMARY KEY

业务唯一字段 UNIQUE KEY uk_xxx

高并发写入 自增 / 雪花 ID 主键

读多写少 可考虑业务唯一字段做主键

六、一句话总结

没有主键时,InnoDB 会用第一个 NOT NULL 的唯一索引当作主键;但它仍然是唯一索引,不是 PRIMARY KEY。

相关推荐
Decay__1 小时前
VMware 安装 SQL Server 双节点 AlwaysOn 可用性组教程 —— WSFC、AG 与侦听器完整部署(系列核心篇)
运维·数据库·sql·mysql·架构
茶栀(*´I`*)2 小时前
SQL 性能分析:从慢查询日志到执行计划的完整定位方法
数据库·sql
艺杯羹2 小时前
1Panel 装好后 ufw 仍是 inactive:一次服务器安全盲区复盘
服务器·数据库·安全·网络安全·系统架构·实战·1panel
code2cat3 小时前
【随笔】MCP工具重试:任务已经创建,响应丢了怎么办
数据库·mcp
wuyk5555 小时前
Spider-第10讲-SQLite持久化与去重
数据库·爬虫·sqlite
乌暮7 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
小此方7 小时前
Re:Mysql数据库基础篇(十二):什么是事务、事务解决了什么问题、事务的四大属性、事务的操作方式
数据库·mysql
csdn_aspnet8 小时前
macOS 10 、Docker 玩轉 MySQL
运维·mysql·macos·docker·容器·mac
flash俊杰8 小时前
v0.5-01 让桌面 AI 助手记得住:预算组装、递归摘要、长期记忆与评估基线
数据库·安全·架构
王中阳Go9 小时前
100 件货卖出 116 件,库存停在 -16
后端·mysql·go