【MySQL】为什么不推荐使用uuid或者雪花id作为主键?

1.原因

使用UUID或雪花ID(Snowflake ID)作为主键并不是完全不推荐的,而是根据具体的应用场景和需求来决定是否适合。

以下是一些不推荐使用UUID或雪花ID作为主键的原因:

  1. 存储空间:UUID是一个128位的值,而雪花ID通常是64位。相比之下,使用较短的整数或自增ID作为主键将占用更少的存储空间。这在大规模的数据库中尤为重要,可以节省磁盘空间、内存和网络带宽。
  2. 索引效率:UUID和雪花ID是随机生成的,没有顺序性可言。这导致在使用这些主键作为索引时,索引树的深度增加,查询效率下降。相比之下,使用自增ID或有序的整数主键可以使索引更加紧凑和快速。
  3. 数据库碎片化:使用UUID作为主键可能会导致数据库碎片化的问题。因为UUID是随机生成的,数据写入时经常涉及到页面的分裂和重组增加了磁盘I/O操作的频率,影响了性能。
  4. 难以读取和调试:由于UUID和雪花ID是较长的字符串或数字,对于人类来说不太易读和理解。在调试、分析以及人工处理数据时,使用较短的整数或自增ID作为主键更加方便。

然而,使用UUID或雪花ID作为主键也有其优势。例如,在分布式环境中,使用UUID或雪花ID可以确保全局唯一性,而不需要单个中心化的发号器。此外,使用UUID可以提供更好的数据隐私保护,因为它们具有较高的随机性。

2.使用uuid(或雪花ID)和自增id的索引结构对比

2.1 使用自增id的内部结构

在这里插入图片描述
在这里插入图片描述
自增的主键的值是顺序的,所以Innodb把每一条记录都存储在一条记录的后面。当达到页面的最大填充因子时候(innodb默认的最大填充因子是页大小的15/16,会留出1/16的空间留作以后的修改):

①下一条记录就会写入新的页中,一旦数据按照这种顺序的方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率不会有页的浪费

②新插入的行一定会在原有的最大数据行下一行,mysql定位寻址很快,不会为计算新行的位置而做出额外的消耗

减少了页分裂和碎片的产生

2.2 使用uuid(或雪花ID)的索引内部结构

在这里插入图片描述
因为uuid相对顺序的自增id来说是毫无规律可言的,新行的值不一定要比之前的主键的值要大,所以innodb无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空。这个过程需要做很多额外的操作,数据的毫无顺序会导致数据分布散乱,将会导致以下的问题:

①:写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO

②:因为写入是乱序的,innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上

③:由于频繁的页分裂页会变得稀疏并被不规则的填充,最终会导致数据会有碎片

在把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)以后,有时候会需要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。

2.3 使用自增id的缺点

  1. 安全问题:如果采用自增主键,可能存在根据ID值爬取数据库记录,有安全风险;
  2. 系统重构:系统重构或者与其他系统集成时,可能存在新老主键冲突
  3. 高并发负载,innodb在按主键进行插入的时候会造成明显的锁争用,主键的上界会成为争抢的热点,因为所有的插入都发生在这里,并发插入会导致间隙锁竞争
  4. Auto_Increment锁机制会造成自增锁的抢夺,有一定的性能损失;
  5. 自增主键有限,要考虑主键长度问题。

参考链接:MySql为什么不推荐使用UUID做主键

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值