MySQL递增主键不连续的四种场景问题及解决

 更新时间:2026年04月29日 09:34:38   作者:又旅行又开拓的绳匠..  
本文解释了MySQL中auto_increment的原理和四种导致自增主键不连续的情况:自增初始值和步长设置不为默认、唯一键冲突、事物回滚、批量插入,每种情况都有详细的解释和具体示例,有助于理解MySQL中的自增主键机制

MySQL中可以设置auto_increment,作用是新增数据时不需要手动添加主键,输入null或未指定值时就会把auto_increment的值赋给自增主键。

一般来说,自增主键都是连续的,但是,有四个场景自增主键不是连续的!(使用的是InnoDB引擎)

第一种、自增初始值和自增步长设置不为 1

InnoDB引擎有两个属性:auto_increment_offset(初始值)和auto_increment_increment(步长),一般默认为1,即初始值1,每次自增1,所以子增值就是1,2,3,4,5...这就是连续的.

如果设置这两个属性,自增值就会从初始值开始,每次加一次步长得到下一个数,比如设置初始值为3,步长为2,那自增值就是3,5,7,9...这就不是连续的了.

第二种、唯一键冲突

插入数据时,如果有设置唯一的字段重复了,那么就会报错,插入失败,但此时系统的自增值还是会增加一次,这是由于insert语句的执行流程导致的:

  • 1.执行器调用引擎准备插入数据(null,1,1)
  • 2.发现没有主键值,获取自增值2(表里已经有数据1,1,1,假设第二个字段重复)
  • 3.将插入的数据改成(2,1,1)
  • 4.自增值变为3
  • 5.执行插入操作,第二个字段重复,报 Duplicate key error,插入失败

这个流程说明自增是在执行插入数据之前,所以哪怕语句失败了,自增值还是会自增,这时候再插入数据就会变成(3,2,1)了

第三种、事物回滚

MySQL里有个rollback,它是TCL语句,叫事务控制语句,比如commit和rollback,前者是提交,后者是回滚,作用是撤销当前事务中已经进行的所有修改,使数据库返回到事务开始之前的状态!

当我们执行了插入操作后,自增值会增加,此时我们回滚,数据会回到插入之前的数据,但自增值不会跟着回到之前的自增值,这么设计的原因是为了提高性能.

因为如果此时有多个并行执行的事务(并行执行时会加锁),而回滚也会回滚自增值的话,就可能会导致主键重复冲突.为了解决这种冲突,要么就是判断赋值自增值时表里是否已经有此自增值,要么把锁的范围扩大到一个事务执行完并提交,无论是哪种方法,都会影响性能,所以才会设计自增值不会回滚。

第四种、批量插入

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

  • 第一次申请自增时,会分配1个值
  • 第二次时,会分配2个值
  • 第三次时,会分配4个值
  • ...

以此类推,同一个语句申请自增时,每次申请的个数都是上一次的两倍

(这里说的批量插入不是insert into table values(),这类语句是可以精准计算出需要多少自增值的,不知道需要多少自增值的语句是insert...select、replace … select 和 load data)

举个例子

有5个数据需要插入,(1,1),(2,2),(3,3),(4,4),(5,5)

  • 第一次申请,申请一个id:1
  • 第二次,申请两个id:2,3
  • 第三次,申请四个id:4,5,6,7

此时自增值就变成了8,下次插入数据时就会把8赋值给主键!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一键安装mysql5.7及密码策略修改方法

    一键安装mysql5.7及密码策略修改方法

    这篇文章主要介绍了一键安装mysql5.7及密码策略修改方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-10-10
  • 连接MySQL出现Host is not allowed to connect to this MySQL server 解决方法详解

    连接MySQL出现Host is not allowed to con

    这篇文章主要给大家介绍了连接MySQL出现Host is not allowed to connect to this MySQL server 解决方法,文中有详细的解决步骤,需要的朋友可以参考下
    2023-08-08
  • Mysql 判断查询条件索引是否生效步骤示例演示

    Mysql 判断查询条件索引是否生效步骤示例演示

    本文给大家介绍MySQL查询条件索引是否生效的完整指南,涵盖步骤、使用说明及示例演示,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-08-08
  • MySQL数据库char与varchar的区别分析及使用建议

    MySQL数据库char与varchar的区别分析及使用建议

    本文主要介绍了mysql中VARCHAR与CHAR字符型数据的差异以及这两种字符型数据在项目中的使用建议,真心不错。值得一看。小编有种受益匪浅的感觉。
    2014-09-09
  • Mysql ALTER TABLE加字段的时候到底锁不锁表

    Mysql ALTER TABLE加字段的时候到底锁不锁表

    本文主要介绍了Mysql ALTER TABLE加字段的时候到底锁不锁表,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 通过实例解析MySql CURRENT_TIMESTAMP函数

    通过实例解析MySql CURRENT_TIMESTAMP函数

    这篇文章主要介绍了通过实例解析MySql CURRENT_TIMESTAMP函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • MySQL定时删除XX天数据示例代码

    MySQL定时删除XX天数据示例代码

    通过使用MySQL的事件调度器,我们可以方便地创建定时任务来定期清理数据库中的过期数据,本文介绍了如何创建定时任务以及如何删除3个月前的数据作为示例,感兴趣的朋友跟随小编一起看看吧
    2023-09-09
  • 数据库中如何通过创建新表来备份操作示例代码

    数据库中如何通过创建新表来备份操作示例代码

    数据库备份是指在特定时间点保存数据库中数据的过程,备份数据通常存储在不同的物理介质上,比如硬盘、磁带或云端存储设备,以防止数据丢失或损坏,这篇文章主要介绍了数据库中如何通过创建新表来备份操作的相关资料,需要的朋友可以参考下
    2025-07-07
  • 在 MySQL 中快速的复制一张表包括表结构和数据

    在 MySQL 中快速的复制一张表包括表结构和数据

    文章介绍了四种复制MySQL表的方法,包括CREATE TABLE...SELECT、CREATE TABLE...LIKE...INSERT、mysqldump工具和物理文件复制,每种方法都有其适用场景和优缺点,面试时,应根据表的大小、结构完整性、效率和适用场景选择合适的方法,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • CentOS7使用rpm包安装mysql 5.7.18

    CentOS7使用rpm包安装mysql 5.7.18

    这篇文章主要为大家详细介绍了CentOS7使用rpm包安装mysql 5.7.18的相关步骤,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06

最新评论