自增、UUID、雪花算法ID对比

ID 是系统开发中最基本的一个字段,针对 ID 目前多种方案:自增、UUID、雪花算法等,下面针对这些方案做一个对比(基于 mysql 数据库):


自增 ID
自增 ID:有序 ID
优势:性能好、存储内容少、不会有页裂变问题、易读
劣势:分布式存储比较麻烦、mysql 有自增的 id 锁会有一定性能损耗(相对的)、容易被猜测数据被爬虫爬取

要支持分布式也可以,就是分表分库的时候设置不同的起始递增的位置
比如:表 A1 起始 101000000000,表 A2 起始 102000000000,这样 ID 就不会相同,预留 10 亿的数据,前面三位作为区分不通表或者机器


UUID
UUID:无序随机 ID,时间戳 + 随机数 + 机器 MAC 等信息
优势:全网唯一、适合分布式分库分表存储、ID 没有规律不会被恶意猜测
劣势:性能 / 性能 / 性能、随机导致数据库存储大量的页 (插入性能会有比较大的影响,数据量非常大的时候查询也会有影响)、存储内容也较大(多了一倍多的存储空间)

关于 UUID 还有一种有序 UUID,有序 UUID 会有更好的性能,Hibernate 依赖包中有关于有序 UUID 的实现类:org.hibernate.id.UUIDHexGenerator。

如果项目中一定要使用 UUID 的话建议使用有序 UUID。


雪花算法
雪花算法:Snowflake,时间戳 + 随机数 + 服务器标记
优势:性能较好、有序、全局唯一适合分布式场景
劣势:存储内容较长、前端 Long 转换有精度丢失问题(需要实现 Json 转换解决精度问题)、服务器时钟回拨问题导致重复 ID (概率较低)、插入性能没有自增 ID 好

精度问题处理:https://www.jianshu.com/p/190a18b3d56c
 

几种 ID 生成方式的压力测试对比:

创建 4 种 ID 类型的表:

自增
CREATE TABLE `test_id` (
  `id` bigint (20) NOT NULL AUTO_INCREMENT COMMENT ' 主键 ',
  `name` varchar (200) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ' 名称 ',
  `remark` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),

  KEY `IDX_CREATETIME0` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1324008 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

雪花
CREATE TABLE `test_snowflakeid` (
  `id` bigint (20) NOT NULL COMMENT ' 主键 ',
  `name` varchar (200) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ' 名称 ',
  `remark` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_CREATETIME1` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

随机 UUID
CREATE TABLE `test_uuid` (
  `id` varchar (100) COLLATE utf8_unicode_ci NOT NULL COMMENT ' 主键 ',
  `name` varchar (200) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ' 名称 ',
  `remark` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_CREATETIME2` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

有序 UUID
CREATE TABLE `test_uuid2` (
  `id` varchar (100) COLLATE utf8_unicode_ci NOT NULL COMMENT ' 主键 ',
  `name` varchar (200) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ' 名称 ',
  `remark` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_CREATETIME3` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


100W 数据

插入对比:
自增: 耗时:180400ms
雪花算法: 耗时:215766ms
随机 UUID: 耗时:719659ms
有序 UUID: 耗时:224371ms

查询 count 对比:
自增:0.5S
雪花算法:0.6S
随机 UUID:2.6S
有序 UUID:0.6S

查询单一记录查询对比:
自增:0.035S
雪花算法:0.032S
随机 UUID:0.040S
有序 UUID:0.035S

时间索引范围查询:

自增:select * from test_snowflakeid where create_time = '2022-02-15 14:01:13'; 0.031S
雪花算法:select * from test_snowflakeid where create_time = '2022-02-15 14:08:18';  0.04S
随机 UUID:select * from test_uuid where create_time = '2022-02-15 14:16:39'; 0.38S
有序 UUID:select * from test_uuid2 where create_time = '2022-02-15 14:30:28'; 0.038S

结论:

插入性能:自增 > 雪花 = 有序 UUID >(3-4 倍) 无序 UUID

查询 Count 性能:自增 > 雪花 = 有序 UUID >(3-4 倍) 无序 UUID

查询单条记录:自增 = 雪花 = 有序 UUID = 无序 UUID 差别不大

查询时间范围索引:自增 > 雪花 = 有序 UUID >(5-10 倍) 无序 UUID

建议开发的时候使用雪花算法或者有序 UUID。

  • 12
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
uuid是一种通用唯一标识符,通常由32位的16进制数字组成,它能够保证全球范围内的唯一性。然而,uuid也有一些弊端。首先,由于uuid的长度较长,当需要存储大量uuid时,会占用较多的空间。其次,uuid的生成算法通常是基于时间戳和随机数生成的,存在并发生成相同uuid的可能性。这会给分布式系统中的数据一致性带来挑战。另外,uuid的生成是一个计算密集型的过程,对服务器的性能要求较高。 为了解决uuid带来的问题,Twitter提出了雪花算法雪花算法是一种分布式唯一ID生成算法,它能够在分布式系统中生成唯一的、有序的、趋势递增的64位ID雪花算法的结构如下: 1. 第1位是符号位,始终为0,表示正数。 2. 接下来的41位是时间戳,精确到毫秒级,可以使用69年。 3. 然后是10位的工作机器号,可以部署1024个节点。 4. 最后是12位的序列号,表示同一毫秒内的自增序号,支持每个节点每毫秒产生4096个ID雪花算法的优点在于,它是有序递增的,可以按照时间顺序排序。由于采用了时间戳和节点编号的组合作为ID的一部分,雪花算法能够保证在大部分场景下的唯一性和有序性。此外,雪花算法的生成速度非常快,不依赖于网络和外部资源。 总的来说,uuid的弊端主要在于长度长、并发生成相同uuid以及计算密集等方面,而雪花算法通过时间戳和节点编号的组合,能够解决uuid的一些问题,实现了分布式环境下的唯一ID生成。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值