MySQL之深入解析自增主键为何不连续
【摘要】众所周知,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,大量的随机IO。自增主键不连续,这是大家已经熟知的知识点,但是也应该有不少朋友不知道为何自增主键不是严格递增呢?
1 概述
1.1 自增起始值和自增步长
MySQL提供了主键自增机制AUTO_INCREMENT,对主键使用,保证主键的唯一性,默认值起始值为1,每次增长量为1,也就是自增起始值auto_increment_offset 和自增步长 auto_increment_increment。
1.2 自增主键存储策略
不同的存储引擎,自增主键存储策略不同。MyISAM的自增值保存到数据文件中;InnoDB引擎的自增值,其实保存在内存中,并且到MySQL8.0版本后,才有了“自增主键持久化”能力。
1.3 自增值修改机制
- 如果自增id插入值为0、null或未指定值,那么就把当前表的自增值AUTO_INCREMENT填到自增字段。
- 如果插入数据时,id指定了具体的值,如果这个具体值不小于自增值AUTO_INCREMENT,则主键值不变,自增值AUTO_INCREMENT=主键值+步长值;否则,自增值AUTO_INCREMENT不变,不存在主键冲突则插入成功。
2 为什么主键不连续自增
- MySQL5.7及以前的版本InnoDB存储引擎不支持自增值持久化,重启导致自增值丢失。
- 事务回滚(自增值不能回退,因为并发插入数据时,回退自增 id 可能造成主键冲突);
- 唯一键冲突(由于表的自增值已变,但是主键发生冲突没插进去,下一次插入主键=现在变了的子增值 +1,所以不连续)。
我发现,2、3点已经不存在了,因为主键自增值AUTO_INCREMENT的更新策略不再遵循“主键冲突进行更新”策略,而是保持不变。