当前位置: 首页 > news >正文

大厂为什么要禁止使用数据库自增主键

大表为何不能用自增主键?

数据库自增主键,以mysql为例,设置表的ID列为自动递增,便可以在插入数据时,ID字段值自动从1开始自动增长,不需要人为干预。

在小公司,或者自己做项目时,设置ID为自动递增,是没有问题的。但是在分布式系统中,自增主键会带来问题,下面举例说明:

有一张商品信息表,表中有3亿条数据,但是3亿条数据是分布在3个数据库中(3个表分片)。前1亿条数据分布在分片1中;中间1亿条数据,分布在分片2;最后1亿条数据分布在分片3中。

问题1:如果单条数据量比较小,在分片1中实际可以容纳1.5亿数据,就无法再进行数据扩展了,因为数据是按照ID范围进行分片的,ID是固定死的,无法在运行期间,进行动态扩展。

问题2:自增主键是数据库层面生成的自增序列,数据库集群只能采用“范围分片”的形式,也就是提前规划好每个分片存储的记录ID。此操作会产生“尾部热点”。

何为尾部热点,在使用范围分片的情况下,测试程序的生成主键是单调递增的,所以新写入的数据往往集中在一个 范围范围内,而范围又是数据调度的最小单位,只能存在于单节点,那么这时集群就退化成单机的写入性能,不能充分利用分布式读写的扩展优势了。当所有写操作都集中在集群的一个节点时,就出现了我们常说的数据访问热点(Hotspot)。

以上面的商品表为例,当数据量达到2.5亿时,数据再进行插入操作时,数据都会进入到分片3中,也就是集中会对分片3这个数据库进行操作,前面两个数据库(分片1、分片2),几乎没有压力。

AB两个数据库,分别采用范围分片和Hash分片的方法,做数据并发处理。可以看到Hash分片的方式效率远高于范围分片看,提高大约2倍。

Hash分片处理效率高,原因是Hash分片不是把数据只写在一个切片上,它是根据ID取模,然后均匀分配在各个切片上,相当于让把压力分摊到各个切片上。

UUID是好的替代方案吗?

如果说自增主键不适用于大数据量分库的表设计,那么是否可以用UUID或者GUID来替代自增主键呢?其实UUID也是不合适的。

UUID是根据当前计算机的时间和其他各种属性计算出来的一个128位长度的字符串,字符串的特点是唯一且无序。

既然是唯一的,那为何不适合作为主键,那就看MySQL的机制。因为UUID是无序的,作为主键会涉及大量索引重排。作为主键,当数据生成时,就自动建立唯一的主键索引。

数据采用B+树的方式进行数据存储,叶子节点按照顺序,1234...进行排列,当要插入一条新数据时,只需要在原有的节点上追加上一个元素,并调整结尾的树形结构。影响的数据范围非常小。

如果使用UUID,就会涉及到索引重排,索引重排以下图为例:

索引重排示意图

当新的数据插入时,整个数据结构都会发生变化。当数据量大时,代价是很大的。

为了解决该问题,也就有了一种分布式且有序的主键生成算法,即雪花算法。

SnowFlake雪花算法是什么?

雪花算法(SnowFlake)是Twitter公司分布式项目采用的ID 生成算法。

雪花算法构成要素

雪花算法构成说明

以时间为依据,结合机器ID及序列,生成的一个定长的数字,这个数字就可以作为主键。它即可以保证是有序的,在分布式情况下,每个分片也是唯一的。 

使用雪花算法时,需要注意时间回拨带来了ID重复问题,也就是如果把服务器时间往回调整,那么生成的值,有可能与之前的值重复。一般不会去随意调整服务器时间,这个问题产生的概率不高。

关于雪花算法的其他内容,参考文章:

SQL-雪花ID算法-全局唯一标识符(GUID)


http://www.mrgr.cn/news/56824.html

相关文章:

  • mybatis 扩展 批量插入
  • 掌握ElasticSearch(三):探索核心概念——文档、索引、分片、倒排索引
  • 【日记】不小心把 Bot 搞炸了(586 字)
  • MYSQL-查看数据库中的存储过程语法(六)
  • SpringBoot个人理财系统:掌控你的资金流向
  • 微信小程序文本收起展开
  • 传统园区与智慧园区:现代化发展的差异和优势
  • @PostConstruct 注解的作用和使用
  • HTML满屏飘字代码
  • Ubuntu22.04环境搭建MQTT服务器
  • 除了HarmonyOS NEXT,华为在原生鸿蒙之夜还带来了哪些重磅新品?
  • android openGL ES详解——混合
  • 当贝连续10天销售额稳居第一!同比增长200%以实力取胜!
  • 庖丁解java(一篇文章学java)
  • kali的下载与配置(未补全)
  • 【Python】数据导入
  • Time-MMD:首个涵盖9大主要数据领域的多域多模态时间序列数据集
  • 某央企下属单位干部分流渠道建设咨询项目纪实
  • Python推荐系统详解:基于协同过滤和内容的推荐算法
  • [001]基于SpringBoot的在线拍卖系统
  • ubuntu clash 配合smartdns
  • Spring Boot框架:论坛网站开发的新选择
  • js实现弹幕效果
  • Python 第七节 魔法圆阵
  • leetcode力扣刷题系列——【构成整天的下标对数目 I】
  • [0155].第6节:IDEA常用插件