设为首页
收藏本站
切换到宽版
门户
Portal
社区
BBS
站长
开发
运维
资源
游戏
产品
登录
立即注册
随客社区
»
社区
›
交流大厅
›
创客汇聚
›
为什么MySQL不推荐使用雪花ID和UUID做主键? ...
返回列表
发布新帖
查看:
26
|
回复:
0
为什么MySQL不推荐使用雪花ID和UUID做主键?
mrkong
mrkong
当前离线
UID
4
星火
贡献
奖金
发表于
前天 15:59
|
查看全部
|
阅读模式
这里或许是互联网从业者的最后一片净土,随客社区期待您的加入!
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
本帖最后由 mrkong 于 2025-8-28 16:01 编辑
在 MySQL 表设计中,主键的选择对性能影响极大。雪花 ID(Snowflake)和 UUID 虽然常用于分布式系统中保证全局唯一性,但在 MySQL 中却并不是最佳的主键选择。本文将从
索引机制、存储原理、性能影响
等角度深入分析原因,并给出最佳实践方案。
一、MySQL 主键的设计核心:聚簇索引与数据组织
1. 聚簇索引的本质
MySQL 的 InnoDB 引擎使用
聚簇索引(Clustered Index)
:
数据行的物理存储顺序与主键索引顺序一致。
主键不仅是唯一标识,也是数据存储的顺序依据。
二级索引存储的是
主键值
而不是数据地址,查询时必须回表。
2. 理想主键的特征
固定长度
:便于快速定位数据页。
顺序增长
:插入时顺序追加,避免频繁页分裂。
紧凑存储
:占用空间小,提高缓存利用率。
二、UUID 做主键的四大性能缺陷
存储空间大
UUID 通常为 36 字符的字符串,如 550e8400-e29b-41d4-a716-446655440000。
CHAR(36):36 字节,VARCHAR(36):37 字节。
对比 BIGINT(8 字节),UUID 占用空间多近 5 倍。
2. 无序性导致索引碎片化
UUID 随机分布,插入时位置不可控。
导致 B+ 树频繁分裂,写入性能大幅下降,索引碎片增加。
3. 字符串比较效率低
UUID 按字典序比较,需要逐字符扫描。
范围查询性能差,无法利用主键的顺序性。
实测:查询性能比自增主键慢 30%+。
4. 影响二级索引性能
二级索引存储主键值,UUID 主键过长导致:
索引体积增大,缓存命中率下降。
回表查询需更多随机 I/O。
三、雪花 ID 的优化与局限性
1. 优势
紧凑存储
:使用 BIGINT(8 字节),比 UUID 高效。
趋势有序
:基于时间戳生成,整体递增,插入较平稳。
分布式唯一
:不同节点生成的 ID 全局唯一。
2. 局限性
非完全顺序
:
同一毫秒内的 ID 顺序由序列号决定,可能局部乱序。
多节点之间的 ID 顺序可能跳跃,仍有页分裂风险。
分布式管理成本高
:
需独立 ID 生成服务。
存在时钟回拨、节点数限制等问题。
四、MySQL 主键的最佳实践
1. 单机场景:自增 ID
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL
) ENGINE=InnoDB;
复制代码
优点
:
顺序插入,页分裂少。
存储空间小,索引紧凑。
插入查询性能最佳。
2. 分布式场景的推荐方案
方案 1:分库分表 + 自增主键
每个分库自增 ID 起始值不同,避免冲突。
方案 2:MySQL 原生 UUID(二进制存储)
INSERT INTO t (id) VALUES (UUID_TO_BIN(UUID()));
SELECT BIN_TO_UUID(id) FROM t;
复制代码
存储空间缩减至 16 字节。
方案 3:分布式 ID 生成器(Leaf、UidGenerator)
基于数据库号段或雪花算法,生成趋势递增 ID。
五、必须使用 UUID/雪花 ID 时的优化策略
UUID 转为二进制存储
:
BINARY(16) 代替 CHAR(36)。
存储效率提升,索引更紧凑。
2. 顺序化插入(适用雪花 ID)
:
应用层按时间戳排序后写入。
高并发场景可能造成插入阻塞。
3. 控制页分裂
:
定期 OPTIMIZE TABLE。
合理设置 innodb_fill_factor。
六、性能对比实测(100 万条数据,MySQL 8.0 InnoDB)
主键类型
插入速度(条/s)
主键索引大小
范围查询耗时
自增 ID (BIGINT)
12,345
8.2MB
12ms
雪花 ID (BIGINT)
10,890
8.2MB
15ms
UUID (CHAR(36))
6,543
38.5MB
28ms
环境:4核8GB,SSD。
七、总结:主键选择的核心原则
优先顺序性
:自增 ID 写入性能最佳。
优先紧凑性
:避免长字符串主键。
分布式权衡
:
单机场景:自增主键。
分布式场景:趋势递增 ID(雪花或号段方案)。
除非有
全局唯一性强需求
,否则不建议直接用 UUID 或雪花 ID 作为 MySQL 主键。若必须使用,应通过
二进制存储 + 顺序化插入
等手段尽量降低性能损耗。
回复
举报
返回列表
发布新帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
快速入口
社区门户
社区首页
随客云计算
重要文档
社区规则
官方公告
关于我们
团队介绍
产品合集
联系我们
532352
028-67879779
tech@isuike.com
Copyright © 2001-2025
Suike Tech
All Rights Reserved.
随客交流社区 (备案号:
津ICP备19010126号
)
|
Processed in 0.120698 second(s), 8 queries , Gzip On, MemCached On.
关灯
在本版发帖
返回顶部
快速回复
返回顶部
返回列表