MySQL学习笔记之MySQL的自增主键为什么不连续(二十三)

声明:本文章内容是根据极客时间中林晓斌的课程《MYSQL45讲》,经过学习,加以自己的理解形成的笔记。具体原文可以到官网进行阅读。如有侵权请,告知删除。

1、自增主键

在MySQL当中AUTO_INCREMENT用来修饰的字段表示,改主键是是自增的。那么自增的主键保存在哪里。不同的引擎保存策略不相同。

  • MyISAM 引擎的自增值保存在数据文件中。
  • InnoDB 引擎的自增值,其实是保存在了内存里;在版本8.0之后才引入持久化;在8.0之前如果发生重启就会选择max+1 为当前的最大值

2、自增值的修改机制

  • 如果插入的是0,null 也就是未制定状态,那么AUTO_INCREMENT的值就为当前id;并且AUTO_INCREMENT为
    AUTO_INCREMENT+步长
  • 如果插入数据的时候制定了 id的值,那么id就取已经存在的值
    新的AUTO_INCREMENT的生成策略为( 假设:新ID 为X;AUTO_INCREMENT为Y)
  • X<Y AUTO_INCREMENT保持不变
  • X≥Y AUTO_INCREMENT=Y

3、什么情况下主键不是连续

  • 1.插入时发生冲突,报错的,自增值变更,是在真正执行插入数据的操作之前操作的,所以发送冲突之后,自增值并不会还原
  • 2.事务回滚,当插入的数据发生回滚时,插入数据时所增加的自增值并不会 还原
  • 3.批量申请id导致主键值不连续
insert into t values(null, 1,1);
insert into t values(null, 2,2);
insert into t values(null, 3,3);
insert into t values(null, 4,4);

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

  1. 语句执行过程中,第一次申请自增 id,会分配 1 个;
  2. 1 个用完以后,这个语句第二次申请自增 id,会分配 2 个;
  3. 2 个用完以后,还是这个语句,第三次申请自增 id,会分配 4 个;
    依此类推,同一个语句去申请自增 id,每次申请到的自增 id 个数都是上一次的两倍。那么这样就会造成最后一次申请的id不能使用完全。但是当下次申请的时候,并不会接着使用。

4、自增锁的策略

自增锁也就是对于 修改自增值的这个操作的锁,当要作自增值操作会获取锁,使用完成,释放后被的事务也就可以申请了,但是锁的释放时机有下面几种情况 并且通过innodb_autoinc_lock_mode 这个参数控制

  • 这个参数的值被设置为 0 时 语句执行结束之后释放锁
  • 这个参数的值被设置为 1 时:
    • 普通 insert 语句,自增锁在申请之后就马上释放;
    • 类似 insert … select 这样的批量插入数据的语句,自增锁还是要等语句结束后才被释放
  • 设置为2 时 锁释放的时机是 申请之后就会释放

猜你喜欢

转载自blog.csdn.net/weixin_43732955/article/details/105181502