前言
在数据时代,无论是单机环境还是分布式环境,都需要保持数据ID的唯一性
针对常见的唯一ID,一般有三种,分别是:自增ID、UUID和雪花ID
自增ID
自增ID(Auto-increment ID)是一种在数据库中常用的主键生成方法,通常用于唯一标识数据库表中的每一行数据
优点
- 唯一性:自增ID保证了每个表中的行都有唯一的标识符,避免了重复数据的问题。
- 简单性:自增ID是一种简单且直观的主键生成方法,易于实现和维护。
- 性能:自增ID可以提高数据库的性能,因为数据库引擎会自动管理并优化自增ID的索引,使数据检索更快速。
- 插入效率:自增ID的顺序插入可以减少数据页的分裂,提高插入效率。
- 隐私性:自增ID不透露关于数据的任何信息,可以保护数据的隐私性。
缺点
- 可预测性:自增ID是连续的数字序列,可能暴露了数据库中数据的规律性,存在安全风险。
- 分布式环境下的问题:在分布式系统中,自增ID的生成可能存在冲突和同步问题,需要额外的处理来确保唯一性。
- 删除数据后的空洞:当删除表中的数据时,可能会留下空洞,导致ID不再是连续的。
- 数据迁移问题:在数据迁移或合并时,可能需要额外考虑自增ID的处理,避免冲突或重复。
- 只适合单机数据库,不能用于分库分表的情况,会产生重复id。
UUID
UUID(Universally Unique Identifier)是一种用于标识信息的唯一标识符,拥有随机、无序,具有非常好的全局唯一性
优点
- 全局唯一性:UUID是全局唯一的标识符,几乎可以保证在不同系统和数据库中生成的UUID都是唯一的。
- 分布式系统支持:在分布式系统中,UUID可以在不同节点上生成唯一的标识符,避免了冲突。
- 随机性:UUID是基于时间和随机数生成的,不易被猜测,提高了安全性。
- 不依赖中心化机制:生成UUID不需要中心化的机制,每个节点都可以独立生成唯一的标识符。
- 无序性:UUID是无序的,不会暴露数据之间的关系,保护了数据的隐私性。
缺点
- 长度:UUID相对于自增ID来说比较长(128位),在存储和索引时占用的空间较大。
- 可读性:UUID是一串十六进制数字和字符,不如自增ID那样直观和易读。
- 性能:生成UUID的算法相对复杂,可能会影响性能,尤其在高并发环境下。
- 不适用于某些场景:在某些情况下,需要连续递增的ID,UUID并不适合。
- 数据库索引问题:由于UUID的无序性,可能会导致索引效率下降,需要额外的处理来优化索引。
雪花ID
有这样一种说法,自然界中并不存在两片完全一样的雪花(世界上没有两片相同的树叶),每一片雪花都拥有自己漂亮独特的形状且是独一无二。
雪花算法也表示生成的 ID 如雪花般独一无二,是一种用于生成分布式系统中唯一ID的算法,由Twitter开发。它的核心思想是将一个64位的ID分成不同的部分,每部分表示不同的信息,例如时间戳、机器ID和序列号。
雪花算法满足唯一性和有序性,避免了分布式系统环境下的ID冲突;并且生成ID的过程中无需依赖数据库等外部系统,减少了系统复杂性。
SnowFlake 算法结构如下:大致分为了无效位、时间位、机器位和序列号位
1)第一位 占用1bit,其值始终是0,没有实际作用(因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0)。
2)时间戳 占用41bit,精确到毫秒,总共可以容纳约69年的时间。
3)工作机器id 占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,做多可以容纳1024个节点。
4)序列号 占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以产生4096个ID。
那么SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢?
同一毫秒的ID数量 = 1024 X 4096 = 4194304
优点
- 全局唯一性:雪花算法生成的ID在分布式系统中保证全局唯一,避免了ID冲突的问题。
- 分布式系统支持:雪花算法适用于分布式系统,每个节点可以独立生成唯一的ID,无需中心化的管理。
- 高性能:雪花算法生成ID的速度较快,适用于高并发的场景。
- 简单:相对于一些复杂的ID生成方案,雪花算法相对简单易懂,易于实现和维护。
- 时间有序:雪花算法生成的ID中包含时间戳,可以保证生成的ID在一定程度上是有序的。
缺点
- 时钟回拨问题:如果系统时钟发生回拨,可能会导致生成的ID重复,需要额外处理时钟同步的问题。
- 依赖机器ID:雪花算法中需要分配机器ID,如果分配不当或者机器ID冲突,可能会导致ID冲突。
- 单点故障:如果分配的机器ID集中在少数几台机器上,这些机器出现故障可能会影响整个系统的ID生成。
- 有序性:虽然时间戳可以保证一定的有序性,但在高并发场景下,可能会出现ID递增速度过快导致性能问题。
- 长度固定:雪花算法生成的ID长度固定,可能会占用较多的存储空间。
比较
生成算法 | 优点 | 缺点 | 长度 | |
---|---|---|---|---|
自增ID | 实现简单,数据递增 | DB单点故障等,需要DBA专业维护 | 递增 | |
UUID | 实现简单,不占带宽 | ID是无序的,查询慢,不适合建立索引 | 32字节 | |
雪花ID | 低位趋势递增,不占带宽,性能高 | 依赖于服务器时间 | 18字节 |