文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

为什么mysql自增主键不是连续的

2024-04-02 19:55

关注

一 前言

       提出这个问题,是因为在工作中发现 mysql 中的 user 表的 id 默认是自增的,但是数据库存储的结果却不是连续的。

       user 表结构:


CREATE TABLE `user` ( 
	`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '递增id', 
	`name` varchar(20),
	`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 
	`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', 
	PRIMARY KEY (`id`),UNIQUE KEY `idx_name` (`name`)) 
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='user表'

       user 表存储:

二 自增值存储说明

1.1  MyISAM 引擎的自增值保存在数据文件中。

1.2  InnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 版本后,才有了“自增值持久化”的能力,也就是才实现了“如果发生重启,表的自增值可以恢复为 MySQL 重启前的值”,具体情况是:

三 自增值修改机制

     在 MySQL 里面,如果字段 id 被定义为 AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:

     根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设,某次要插入的值是 X,当前的自增值是 Y。

     新的自增值生成算法是:从 auto_increment_offset 开始,以 auto_increment_increment 为步长,持续叠加,直到找到第一个大于 X 的值,作为新的自增值。其中,auto_increment_offset 和 auto_increment_increment 是两个系统参数,分别用来表示自增的初始值和步长,默认值都是 1。

四 自增值修改时机


insert into user values(null, '张三'); 

  1 当执行上述 SQL 时,执行器调用 InnoDB 引擎接口写入一行,传入的这一行的值是 (0,"张三");

  2 InnoDB 发现 SQL 没有指定自增 id 的值,获取 user 表当前的自增值 2;

  3 将传入的行的值改成 (2,"张三");

  4 将表的自增值改成 3;

  5 继续执行插入数据操作。

五 导致自增值不连续的原因

5.1 唯一键冲突

       假设执行 SQL 的时候 user 表 id = 10,此时在内存中的自增 id 为11,此时发生唯一键冲突写库失败,则 user 表没有 id = 10 这条记录,之后 id 从11开始写入,因此 id 是不连续的。

5.2 事务回滚

       假设同时需要对 user、staff 表进行写库操作,执行 SQL 的时候 user 表 id = 10,此时在内存中的自增 id 为11;staff 表 id = 20,此时内存中的自增 id 为21,一旦事务执行失败,事务回滚,写库失败,则 user 表没有 id = 10 这条记录,staff 表没有 id = 20 这条记录,user 表从11开始写入,staff 表从21开始写入,如此产生 id 不连续的现象。

5.3 批量写库操作

       对于批量插入数据的语句,MySQL 有一个批量申请自增 id 的策略:

       1. 语句执行过程中,第一次申请自增 id,会分配 1 个;

       2. 1 个用完以后,这个语句第二次申请自增 id,会分配 2 个;

       3. 2 个用完以后,还是这个语句,第三次申请自增 id,会分配 4 个;

       依此类推,同一个语句去申请自增 id,每次申请到的自增 id 个数都是上一次的两倍。

       假设批量往 user 表中写入四条记录,则这四条记录将分为三次申请id,

       第一次分配到 id = 1,第二次分配到 id = 2、3 ,第三次分配到 id = 4、5、6、7,当批量写入四条记录之后,id = 1、2、3、4将会入库,但是 id = 5、6、7就被废弃了,下一个 id 从8开始。

六 参考文档 

https://time.geekbang.org/column/intro/139 

到此这篇关于为什么mysql自增主键不是连续的 的文章就介绍到这了,更多相关mysql自增主键连续内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯