为什么不推荐用 UUID 作为 Mysql 的主键

学习改变命运,技术铸就辉煌。

大家好,我是銘,全栈开发程序员。

UUID 是什么

我们先来了解一下 UUID 是什么?UUID 是指Universally Unique Identifier,翻译为中文是通用唯一识别码,UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID,就不需考虑数据库创建时的名称重复问题。

UUID 的十六个八位字节被表示为 32个十六进制数字,以连字号分隔的五组来显示,形式为 8-4-4-4-12,总共有 36个字符(即三十二个英数字母和四个连字号)。例如:

123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

能否用 UUID 做主键

先说答案 , 能,但是性能会比使用自增主键差一些,那原因是什么,我们具体分析:

我们平时建表的时候,一般都像下面这样,不会去使用 UUID,使用AUTO INCREMENT直接把主键 id 设置成自增,每次 +1

sql 复制代码
CREATE TABLE `user`(
`id` int NOT NULL AUTO INCREMENT COMMENT '主键',
`name` char(10) NOT NULL DEFAULT '' COMMENT '名字',
 PRIMARY KEY (`id`)
 )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

那为什么把主键设置成自增呢, 我们在数据库保存数据的时候,就类似与下面的表格一样,这每一行数据,都是**保存在一个 16K 大小的页里 **。

id name age
1 张三 11
2 李四 22
3 王五 33

每次都去遍历所有的行性能会不好,于是为了加速搜索,我们可以根据主键 id,从小到大排列这些行数据,将这些数据页用双向链表的形式组织起来,再将这些页里的部分信息提取出来放到一个新的 16kb 的数据页里,再加入层级的概念。于是,一个个数据页就被组织起来了,成为了一棵 B+ 树索引。

当我们在建表 sql 里面声明 AUTO INCREMENT 的时候,myqsl 的 innodb 引擎,就会为主键 id 生成一个主键索引,里面就是通过 B+ 树的形式来维护这套索引。

那么现在,我们需要关注两个点,

  1. 数据页大小是固定的 16k
  2. 数据页内,以及数据页之间,数据主键 id 是从小到大排序的

所以,由于数据页大小固定了 16k ,当我们需要插入一条数据的时候,数据页就会慢慢的被放满,当超过 16k 的时候,这个数据页就可能会进行分裂。

针对 B+ 树的叶子节点,如果主键是自增的 ,那么它产生的 id 每次都比前次要大,所以每次都会将数据家在 B+ 树的尾部,B+ 树的叶子节点本质是双向链表,查找它的首部和尾部,时间复杂度 O(1),如果此时最末尾的数据也满了,那创建个新的页就好。

如果bb,上次 id=12111111,这次 id=343435455,那么为了让新加入数据后 B+ 树的叶子节点海涅那个保持有序,那么就需要旺叶子节点的中间找,查找的时间复杂度是 O(lgn),如果这个页满了,那就需要进行页分裂,并且页分裂的操作是需要加悲观锁的。

所以,我们一般都建议把主键设置成自增,这样可以提高效率,提高性能

那什么情况下不设置主键自增

mysql分库分表下的id

在分库分表的情况下,插入的 id 都是专门的 id 服务生成的,如果要严格按照自增的话,那么一般就会通过 redis 来生成,按批次去获得,比如一次性获取几百个,用完了再去获取,但是如果 redis 服务挂了,功能就完全没法用了,那有么有不依赖与第三方组件的方法呢?

雪花算法

使用时间戳+机器码+流水号,一个字段实现了时间顺序、机器编码、创建时间。去中心化,方便排序,随便多表多库复制,并可抽取出生成时间,雪花ID主要是用在数据库集群上,去中心化,ID不会冲突又能相对排序。

总结

一般情况下,我们不推荐使用 UUID 来作为数据库的主键,只有分库分表的时候,才建议使用 UUID 来作为主键。

相关推荐
上山的月6 分钟前
MySQL -函数和约束
数据库·mysql
zhcf9 分钟前
【MySQL】十三,关于MySQL的全文索引
数据库·mysql
丁总学Java18 分钟前
要查询 `user` 表中 `we_chat_open_id` 列不为空的用户数量
数据库·mysql
抓哇能手18 分钟前
数据库系统概论
数据库·人工智能·sql·mysql·计算机
KELLENSHAW3 小时前
MySQL45讲 第三十七讲 什么时候会使用内部临时表?——阅读总结
数据库·mysql
四七伵3 小时前
MySQL外键类型与应用场景总结:优缺点一目了然
mysql
core5124 小时前
flink cdc各种数据库 jar下载地址
mysql·oracle·flink·jar·oceanbase·cdc
别致的影分身5 小时前
MySQL 常用程序介绍
数据库·mysql
HD2436088365 小时前
【mysql】id主键列乱了之后,重新排序(可根据日期顺序)
数据库·sql·mysql
qq_448941086 小时前
6、mysql的MHA故障切换
数据库·mysql