0
点赞
收藏
分享

微信扫一扫

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

残北 2023-01-05 阅读 141

𝑰’𝒎 𝒉𝒉𝒈, 𝑰 𝒂𝒎 𝒂 𝒈𝒓𝒂𝒅𝒖𝒂𝒕𝒆 𝒔𝒕𝒖𝒅𝒆𝒏𝒕 𝒇𝒓𝒐𝒎 𝑵𝒂𝒏𝒋𝒊𝒏𝒈, 𝑪𝒉𝒊𝒏𝒂.

  • 🏫 𝑺𝒉𝒄𝒐𝒐𝒍: 𝑯𝒐𝒉𝒂𝒊 𝑼𝒏𝒊𝒗𝒆𝒓𝒔𝒊𝒕𝒚
  • 🌱 𝑳𝒆𝒂𝒓𝒏𝒊𝒏𝒈: 𝑰’𝒎 𝒄𝒖𝒓𝒓𝒆𝒏𝒕𝒍𝒚 𝒍𝒆𝒂𝒓𝒏𝒊𝒏𝒈 𝒅𝒆𝒔𝒊𝒈𝒏 𝒑𝒂𝒕𝒕𝒆𝒓𝒏, 𝑳𝒆𝒆𝒕𝒄𝒐𝒅𝒆, 𝒅𝒊𝒔𝒕𝒓𝒊𝒃𝒖𝒕𝒆𝒅 𝒔𝒚𝒔𝒕𝒆𝒎, 𝒎𝒊𝒅𝒅𝒍𝒆𝒘𝒂𝒓𝒆 𝒂𝒏𝒅 𝒔𝒐 𝒐𝒏.
  • 💓 𝑯𝒐𝒘 𝒕𝒐 𝒓𝒆𝒂𝒄𝒉 𝒎𝒆:𝑽𝑿
  • 📚 𝑴𝒚 𝒃𝒍𝒐𝒈: 𝒉𝒕𝒕𝒑𝒔://𝒉𝒉𝒈𝒚𝒚𝒅𝒔.𝒃𝒍𝒐𝒈.𝒄𝒔𝒅𝒏.𝒏𝒆𝒕/
  • 💼 𝑷𝒓𝒐𝒇𝒆𝒔𝒔𝒊𝒐𝒏𝒂𝒍 𝒔𝒌𝒊𝒍𝒍𝒔:𝒎𝒚 𝒅𝒓𝒆𝒂𝒎

1 理论

1.1 从存储大小上

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

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

  • 雪花算法(以百度的UidGenerator为例):
    在这里插入图片描述
    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条数据
数据插入时间图如下:
自增:
请添加图片描述
UUID:
请添加图片描述
雪花id:
在这里插入图片描述
从图上看来,自增和雪花id性能基本上一样,uuid就比较差了。

总结

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

举报

相关推荐

0 条评论