39-自增主键
目录
MySQL 对自增值的保存策略
-
在 MySQL 5.7 及之前的版本
自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值 max(id),然后将 max(id)+1 作为这个表当前的自增值。
举例来说,如果一个表当前数据行里最大的 id 是 10,AUTO_INCREMENT=11。这时候,我们删除 id=10 的行,AUTO_INCREMENT 还是 11。但如果马上重启实例,重启后这个表的 AUTO_INCREMENT 就会变成 10。也就是说,MySQL 重启可能会修改一个表的 AUTO_INCREMENT 的值。
-
在 MySQL 8.0 版本
将自增值的变更记录在了 redo log 中,重启的时候依靠 redo log 恢复重启之前的值。
自增值修改机制
在 MySQL 里面,如果字段 id 被定义为 AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:如果插入数据时 id 字段指定为 0、null 或未指定值,那么就把这个表当前的 AUTO_INCREMENT 值填到自增字段;如果插入数据时 id 字段指定了具体的值,就直接使用语句里指定的值。根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设,某次要插入的值是 X,当前的自增值是 Y。
如果 X<Y,那么这个表的自增值不变;如果 X≥Y,就需要把当前自增值修改为新的自增值。
其他网友总结
在什么场景下自增主键可能不连续?
- 1:唯一键冲突
- 2:事务回滚
- 3:自增主键的批量申请
深层次原因是,不判断自增主键是否已存在和减少加锁的时间范围和粒度->为了更高的性能->自增主键不能回退->自增主键不连续
自增主键是怎么做的唯一性的
自增值加1,自增锁控制并发
自增主键的生成性能如何
这个需要测试一下,数据库的自增主键也用做生成唯一数字,作为其他单号,比如:并发量小的订单号,性能可能一般。
自增主键有最大值吗?如果有,到了怎么办?
最大值应该有,因为数字总有个范围,到了当做字符串的一部分,然后再自增拼接上另一部分,貌似也可以。
自增主键的作用?保存机制?修改机制?
作用:让主键索引尽量地保持递增顺序插入,避免页分裂,使索引更紧凑。
保存机制:不同的存储引擎不一样。
-
MyISAM 引擎的自增值保存在数据文件中。
-
InnoDB 引擎的自增值,先是保存在了内存里,到了 MySQL 8.0 版本后,才有了“自增值持久化”的能力,放在了redolog里。
修改机制: 在 MySQL 里面,如果字段 id 被定义为 AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:
- 1:如果插入数据时 id 字段指定为 0、null 或未指定值,那么就把这个表当前的 AUTO_INCREMENT 值填到自增字段;
- 2:如果插入数据时 id 字段指定了具体的值,就直接使用语句里指定的值。
根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设,某次要插入的值是 X,当前的自增值是 Y。
- 1:如果 X<Y,那么这个表的自增值不变;
- 2:如果 X≥Y,就需要把当前自增值修改为新的自增值。