news 2026/7/8 13:00:17

【Mysql】唯一索引

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Mysql】唯一索引

【Mysql】唯一索引

  • 【一】前置基础
  • 【二】唯一索引底层原理
    • 【1】结构组成
    • 【2】唯一性约束怎么实现
      • (1)插入 / 更新前校验(核心)
      • (2)加锁逻辑(和普通索引最大差异)
      • (3)唯一索引 vs 主键索引
      • (4)联合唯一索引
    • 【3】使用唯一索引后会不会出现重复数据
  • 【三】优缺点
    • 【1】优点
    • 【2】缺点
  • 【四】补充

【一】前置基础

InnoDB 存储引擎下:
(1)所有索引都是B + 树;
(2)主键是聚簇索引,数据行本身存在主键叶子节点;
(3)普通索引、唯一索引都是二级索引(辅助索引)。

【二】唯一索引底层原理

【1】结构组成

唯一索引 B + 树叶子节点存储:[索引键值,主键值]

索引键:建索引的字段(要求全局唯一,允许 1 个 NULL)
主键:用于回表查询完整行数据

对比普通二级索引:结构完全一样,唯一区别是写入时唯一性校验逻辑。

【2】唯一性约束怎么实现

(1)插入 / 更新前校验(核心)

执行 INSERT / UPDATE 时,InnoDB 通过 B + 树快速查找当前索引键是否已存在:
1-根据索引值定位到对应叶子页;
2-页内二分查找匹配记录;
3-若找到相同非 NULL 值 → 直接抛出 Duplicate entry;
4-不存在则正常写入。

注意:唯一索引允许多条 NULL?不,仅允许一条 NULL
逻辑:NULL != NULL,理论上能存多个 NULL,但 InnoDB 限制唯一索引最多一条 NULL。

(2)加锁逻辑(和普通索引最大差异)

(1)普通二级索引:范围扫描会加临键锁,可能幻读;
(2)唯一索引等值匹配:
精准命中唯一一条数据时,退化为行锁,不会锁间隙,并发更好;
找不到数据才会加间隙锁防止插入。

(3)唯一索引 vs 主键索引

(1)主键索引(PRIMARY)
1-聚簇索引,叶子存完整行;
2-不允许 NULL;
3-一张表只能一个;

(2)UNIQUE 唯一索引
1-二级索引,叶子只存主键;
2-允许单个 NULL;
3-一张表可多个;
4-需要回表拿数据。

(4)联合唯一索引

UNIQUE idx_a_b(a,b)
唯一性判定是组合整体唯一,单字段可重复,只要组合不重复即可。
底层 B + 树按 (a,b) 联合值排序,插入时校验组合值全局唯一。

【3】使用唯一索引后会不会出现重复数据

(1)场景 1:字段存 NULL,多条空记录(最常见)
业务上你认为 “手机号不能为空”,但代码没做校验,数据库允许多条手机号 NULL,看起来是重复数据。
解决:业务层判空 + 字段加 NOT NULL。

(2)场景 2:并发插入,无分布式锁(分库分表 / 多实例)
单库单表 InnoDB 中:唯一索引自带行锁,并发插入同一值会阻塞,不会重复。
但以下架构会产生重复:
分库分表:唯一索引仅单表生效,不同分片可以存相同唯一值;
多库 / 多实例无全局锁:两个服务同时校验不存在,并行插入,本地唯一索引互不感知,最终两条重复数据;
读写分离,读从库校验再写主库:从库同步延迟,读到旧数据,导致重复插入。
单库 InnoDB 不会出现这个问题,底层唯一索引写入时加排他锁拦截并发。

方案
(1)字段非空:唯一业务字段添加 NOT NULL,杜绝多条 NULL;
(2)单库场景依赖唯一索引兜底:InnoDB 单表并发插入天然防重;
(3)分布式 / 分库分表:
方案 A:全局唯一 ID(雪花号)替代手机号等业务唯一键;
方案 B:Redis 分布式锁 + 唯一索引双重校验;
方案 C:统一路由分片字段,把唯一键作为分片键;

【三】优缺点

【1】优点

(1)自动实现唯一性约束
数据库层面兜底,不用业务代码判断去重,防止并发场景下重复数据(业务查询校验存在并发漏洞)。
(2)等值查询性能优于普通索引
等值精准匹配时,数据库明确最多一条数据,匹配到即停止遍历;普通索引要读完所有相同值。
(3)减少业务编码复杂度
不用额外加分布式锁、SELECT 判断去重,降低重复写入 bug 概率。
(4)支持快速去重检索
DISTINCT 查询、去重统计会直接利用唯一索引优化,无需额外排序。
(5)锁粒度更小,并发更高
等值命中唯一记录时只加行锁,无间隙锁,减少锁冲突、死锁概率。

【2】缺点

(1)写入性能损耗更大
每次插入 / 更新都必须做唯一性查找校验,多一次 B + 树查询;大批量导入数据时速度明显慢于普通索引。
(2)失效场景多,容易引发死锁 / 锁等待
插入冲突时会阻塞等待持有锁的事务提交;
高并发插入重复值会大量锁等待,拖慢接口。
(3)不适合高频变更字段
更新唯一索引字段会导致 B + 树节点分裂、页移动,产生大量页分裂、undo 日志、redo 日志,IO 飙升。
(4)NULL 行为容易踩坑
只能存一条 NULL,如果业务需要多字段可空且整体唯一,逻辑容易混乱。
(5)占用额外存储空间
作为二级索引,独立一棵 B + 树,相比无索引多存储开销;联合唯一索引存储成本更高。
(6)批量导入场景阻塞严重
大量数据导入有重复风险时,唯一性校验串行化,导入速度远低于普通索引;
大批量数据建议先删唯一索引,导入完成再重建。
(7)无法使用 change buffer 优化写入(关键性能短板)
InnoDB change buffer 用来缓存普通索引的写操作,减少随机 IO;
唯一索引不能使用 change buffer,每次写入必须立刻刷磁盘校验唯一性,随机 IO 暴涨,写入压力大。

【四】补充

(1)唯一索引 vs 业务唯一约束(代码去重)
只用代码去重:高并发下存在竞态条件,同一时刻两条请求同时查询无数据,同时插入,产生重复;
只用唯一索引:写入失败会抛异常,业务需要捕获 Duplicate entry 异常做重试 / 提示。

(2)推荐用唯一索引
手机号、身份证、订单号、设备唯一标识、用户唯一业务编码等强唯一业务字段。

(3)不推荐唯一索引
日表、日志表批量导入海量数据;
频繁更新的业务字段;
仅做查询、无强去重要求的字段;
高并发实时写入、吞吐敏感场景(可业务层分布式锁兜底)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/8 12:53:39

超融合基础设施全解析:国产头部厂商产品矩阵与适用场景

2026年,随着VMware永久授权体系的终结与订阅制的全面落地,国内大中型企业的IT决策者正面临一个紧迫而复杂的课题:如何在窗口期内,选出一套能够平稳承接原有虚拟化资产、且能支撑未来数年业务稳定运行与AI演进的替代底座。"能…

作者头像 李华
网站建设 2026/7/8 12:53:20

深度探索FOC轮腿机器人:3大核心技术架构与实战调优指南

深度探索FOC轮腿机器人:3大核心技术架构与实战调优指南 【免费下载链接】foc-wheel-legged-robot Open source materials for a novel structured legged robot, including mechanical design, electronic design, algorithm simulation, and software development.…

作者头像 李华
网站建设 2026/7/8 12:52:48

HashCalculator终极指南:5分钟掌握文件哈希值批量计算与校验

HashCalculator终极指南:5分钟掌握文件哈希值批量计算与校验 【免费下载链接】HashCalculator 哈希值计算工具,批量计算/批量校验/查找重复文件/改变哈希值等,支持集成到系统右键菜单 项目地址: https://gitcode.com/gh_mirrors/ha/HashCal…

作者头像 李华
网站建设 2026/7/8 12:49:16

3步快速诊断和修复MoviePilot TMDB连接问题的完整指南

3步快速诊断和修复MoviePilot TMDB连接问题的完整指南 【免费下载链接】MoviePilot NAS媒体库自动化管理工具 项目地址: https://gitcode.com/gh_mirrors/mo/MoviePilot MoviePilot作为专业的NAS媒体库自动化管理工具,其核心功能依赖于TMDB(TheMo…

作者头像 李华
网站建设 2026/7/8 12:49:07

asdf:一个 CLI 工具管理多语言运行环境

文章目录asdf:一个 CLI 工具管理多语言运行环境asdf:一个 CLI 工具管理多语言运行环境 asdf 是一个用于管理多语言运行环境版本的 CLI 工具,目前在 GitHub 上获得了 25,426 个 Star。 它的核心定位是用一个命令行工具替代 nvm、rbenv、pyenv…

作者头像 李华
网站建设 2026/7/8 12:45:57

politic politics political

politic 简要解析(美式发音词性/词义/发音对比 political) 一、音标(美音) politic /ˈpɑːlətɪk/ 形容词political /pəˈlɪtɪkl/ 形容词 发音变化关键点 重音完全移位: politic:重音在首音节 PAHpol…

作者头像 李华