文章目录
- 一. MySQL的自增主键
- 二. UUID
- 三. 雪花ID(推荐)
我的博客地址
一. MySQL的自增主键
适合单表的情况, 在分布式分库分表下可能会有一些问题
-
主键冲突问题
在分布式系统中,多个数据库节点独立生成自增主键,很容易出现重复的主键值。例如,多个节点都从1开始递增,会导致主键冲突 -
全局唯一性无法保证
自增主键仅在单个数据库实例中唯一,无法保证在分布式环境下的全局唯一性。这使得在跨节点操作时容易出现重复主键
二. UUID
主要的缺点: UUID是随机生成的,没有顺序性,这会导致数据库的B树索引结构不够紧凑。在插入数据时,由于UUID的随机性,索引页可能会频繁分裂,导致索引碎片化。这种碎片化会增加磁盘I/O操作,降低查询性能。此外,UUID的无序性也使得范围扫描变得低效
解决: 使用有序UUID
MySQL 8.0引入了uuid_to_bin
函数,可以将UUID的时间高位和低位进行互换,从而生成有序的UUID。这种方式既保留了UUID的唯一性,又解决了无序性问题,同时还能优化索引性能。
三. 雪花ID(推荐)
-
工作原理
雪花算法生成的是一个64位的整数ID,由以下几部分组成:- 符号位(1位):始终为0,表示生成的ID是正整数。
- 时间戳(41位):记录生成ID的时间戳(毫秒级),可以支持大约69年的时间。
- 机器ID(10位):共10位,用于区分不同的数据中心和机器,支持最多1024个节点。
- 序列号(12位):在同一毫秒内生成不同的ID,支持每毫秒生成4096个不同的ID。
-
优点
- 全局唯一性:通过时间戳、数据中心ID、机器ID和序列号的组合,确保生成的ID在全局范围内是唯一的。
- 有序性:由于ID中包含时间戳,生成的ID大致有序,便于排序。
-
缺点
- 依赖服务器时间:如果服务器时钟回拨,可能会导致生成重复的ID。
- 时间戳位数有限:虽然41位时间戳可以支持69年,但对于某些长期运行的系统可能需要调整。
-
解决时钟回拨问题
- 外部时间同步机制
利用NTP(网络时间协议)或PTP(精确时间协议)来校正系统时钟,尽量避免时钟回拨 - 等待重试策略
当检测到时钟回拨时,服务可以暂时拒绝生成新的ID,等待一段时间后重试, 直到系统时钟恢复到正常状态(至少大于或等于上次生成ID时的时间戳)。这种方法可以确保ID的严格递增性,但可能会在时钟调整期间暂停服务,对系统性能造成一定的影响。 - 扩展位
在ID结构中增加额外的位来处理时钟回拨。例如,可以使用额外的位来记录时钟回拨的次数,从而避免ID重复。即可以将机器码拆分成时钟序列(3位)和机器码(7位),通过调整时钟序列来处理回拨。
- 外部时间同步机制