不推荐使用 UUID 作为 MySQL 主键
不推荐使用 UUID 作为 MySQL 主键的原因
在 MySQL 中,尤其是 InnoDB 存储引擎下,UUID 作为主键存在多方面的问题,主要体现在性能、存储、可读性和并发控制等方面。
1. 性能问题
- 聚簇索引失效:InnoDB 使用主键构建聚簇索引,数据按主键顺序存储。UUID 为无序的随机值,会导致数据分布不均、频繁页分裂,降低缓存命中率,进而影响插入和查询性能。
- 写入性能下降:UUID 无序性导致插入操作常落在随机位置,更容易引起索引页分裂和页重排,显著降低写入效率。
- 磁盘 I/O 增加:频繁的页分裂和结构调整会放大磁盘 I/O,尤其在高并发写入场景下表现更明显。
2. 存储空间开销
- UUID 占用 16 字节(128 位),远大于 INT(4 字节)或 BIGINT(8 字节)。
- 主键体积增大,导致索引更占内存和磁盘空间,同时降低缓存效率。
3. 主键可读性差
- UUID 一般以长字符串或十六进制表现,难以人工阅读、记忆和排查问题。
- 相比之下,自增 ID 更简洁、易于管理和调试。
4. 不利于顺序插入
- UUID 导致插入位置随机,触发频繁的页分裂和磁盘跳转写入。
- 自增 ID 则可实现顺序插入,支持磁盘顺序写入和预读优化,提高性能。
5. 并发控制能力弱
- UUID 导致索引结构频繁调整,易产生热点页冲突,加剧锁竞争,影响并发性能。
- 自增 ID 天然具备顺序性,有助于减少行锁冲突与死锁风险。
6. 分布式场景中的局限性
- 虽然 UUID 可保证跨系统唯一性,但在单机 MySQL 实例中,该特性并不必要,反而引入性能和存储开销。
7. 推荐替代方案
- 单机环境:推荐使用数据库自增 ID 或 Snowflake 算法生成的趋势递增 ID。
- 分布式环境:推荐使用 Snowflake 算法、美团 Leaf(Segment/Snowflake 模式)或滴滴 TinyID,生成高性能、全局唯一、趋势递增的分布式 ID。
总结
虽然 UUID 能保证全局唯一性,但在单机 MySQL 中,其随机性带来的 索引效率低、存储成本高、写入性能差、并发冲突严重 等问题,使其不适合作为主键。
推荐使用 自增 ID 或 趋势递增的分布式 ID,在保证唯一性的同时,更具性能和扩展性优势。
如需,我还可以为该笔记生成 Markdown 格式、配图、或思维导图结构。是否需要进一步处理?