mysql的auto_increment

auto_increment作用:用来指定一个自增的初始值; 如果不指定值默认初始值为1

  1. 建表语句

  2. 插入数据

    插入第一个数据可以看到id是从2开始

  3. 自增主键不能保证连续递增
    在空表执行insert into aa values(null,1,1); 插入一条数据后,再执行show create table命令

    表定义中AUTO_INCREMENT=3,表示下一次插入数据时,如果要自动生成自增值,会生成id=3。
    自增值保存在表结构定义里。实际上,表结构定义存放在后缀名为.frm的文件中,但并不会保存自增值。

    不同引擎对于自增值保存策略不同:

    • MyISAM引擎的自增值保存在数据文件中
    • InnoDB引擎的自增值,是保存在内存中,到MySQL8.0版本后,才有了“自增值持久化”的能力;如果发生重启,表的自增值可以恢复为MySQL重启前的值
      1)在MySQL5.7及之前的版本,自增值保存在内存中,并没有持久化。每次重启后,第一次打开表的时候,会去找自增值的最大值max(id),将max(id)+1作为这个表当前的自增值。
      例如,表中当前数据行最大的id是10,AUTO_INCREMENT=11。这时我们删除id=10的行,AUTO_INCREMENT还是11。如果马上重启,重启后这个表的AUTO_INCREMENT会变为10。
      2)在MySQL8.0版本,将自增值的变更记录在redo log中,重启的时候依靠redo log恢复重启之前的值

    自增值修改机制

    在MySQL中,如果字段id被定义为AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:
    1)如果插入数据时id字段指定为0、null或者未指定值,就把这个表当前的AUTO_INCREMENT值天道自增字段;
    2)如果插入数据时id字段指定了具体的值,就直接使用语句中指定的值。

    根据要插入的值和当前自增值的大小关系,自增值的变更结果也会不同。假设,某次要插入的值为x,当前的自增值是y
    1)如果x<y, 那么这个表的自增值不变;
    2)如果x>=y,需要把当前自增值修改为新的自增值
    新的自增值生成算法:从auto_increment_offset开始,以auto_increment_increment为步长,持续叠加,直到找到一个大于x的值,作为新的自增值。
    auto_increment_offset和auto_increment_increment是系统参数,分别用来表示自增的初始值和步长,默认值是1

auto_increment_offset和auto_increment_increment都为1的情况下,自增主键id不能保证是连续的,什么原因?
假设上述表aa中,已经有了(1,1,1)这条记录,这时再插入一条数据

insert into aa values(null, 1, 1);

InnoDB发现没有指定自增id,获取表中当前的自增值2;传入行改为(2,1,1);将表的自增值改为3;执行插入操作的时候由于c=1已经存在,报错。
当前表中保存的auto_increment=3。可以使用show create table aa; 查看
当有新数据插入的时候,拿到的自增id=3 --> 出现了自增主键不连续的情况。

引起自增主键不连续有两种原因:
1. 唯一索引冲突
2. 事务回滚(事务中执行insert会使自增主键+1,回滚后不会撤销)

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值