MySQL:关于ID的选择问题,自增/UUID/雪花ID

’ , , .

  • :
  • : ’ , , , .
  • : ://.../

  • MySQL:关于ID的选择问题,自增/UUID/雪花ID_第1张图片

1 理论

1.1 从存储大小上

  • UUID:
System.out.println(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8).length);

36个字节也就是36*8个bit,去掉4个’-'也就是32个字节

  • 雪花算法(以百度的UidGenerator为例):
    MySQL:关于ID的选择问题,自增/UUID/雪花ID_第2张图片
    64bit的long也就是说,8个字节。

  • 自增ID,可以是int也可以是bigint也就是long。4字节或者8字节。

1.2 数据结构-B+树索引

根据上一个博客MySQL:关于innodb里面的聚集索引组成结构。B+树。,我们知道了聚集索引的索引结构,索引是B+树的结构,像单调递增的雪花id和自增id都是递增的,那么他们就会一直操作数据页的最后一页,一个记录一个记录往里面添加就行,添加完了再在一个新的页上面去添加,那么有页的分裂过程吗?没有!反看UUID,uuid你知道该插在哪吗?你不知道,因为它是随机的,如果在一个满的页里插入一个记录,那么就会导致页的分裂,如果碰巧B+树的节点也满了,B+树不得进行调整来维持B+树的,特性。

1.3 键值比较性能

数字的比较的性能要远远高过字符串的比较,那么多字符串进行比较,每插入一个记录,都是从上向下进行比一次的过程,这个不用多说,两个速度差很多。

1.4 IO

CPU是不直接读磁盘的,得读进内存当中,那么CPU是一页一页将磁盘中 的数据读到内存中去的,根据局部性原理,cpu倾向把连续的页预读进内存中去,UUID的页是随机的零散的,那么就势必需要读更多的页,而自增ID和雪花都是局部页上面进行的操作。

1.5 并发程度

UUID和雪花都支持并发的,但是auto_increment自增,懂的都懂是阻塞的,一个一个排队用。

1.6 多库多表问题

自增的id属于表里面唯一,要是几个表合并那肯定是没法合并的,起冲突了呀,在业务上,你有多少数据可以从id上判断出来了。

1.7 生成的位置

uuid和雪花均由客户端生成,不占用MySQL资源,而自增就需要MySQL自己去做。

2 实验

测试数据 一共6163561条,真实数据,非人造
CPU i7 12700F
每1000条数据插入一次(批处理的,不是一条一条插,1000,1000插)
插入工具,mybatis-plus,jdbc连接已打开rewrite

总左边是ms,横坐标是每1000条数据
数据插入时间图如下:
自增:
MySQL:关于ID的选择问题,自增/UUID/雪花ID_第3张图片
UUID:
MySQL:关于ID的选择问题,自增/UUID/雪花ID_第4张图片
雪花id:
MySQL:关于ID的选择问题,自增/UUID/雪花ID_第5张图片
从图上看来,自增和雪花id性能基本上一样,uuid就比较差了。

总结

这么看来雪花算法好像是比较全面的,但是有一个最大的问题就是时钟回拨的问题。百度的生成器里面,已经解决了这个问题。

你可能感兴趣的:(MySQL,mysql,数据库,java)