Mysql插入数据时,怎么让自增的主键续接表当前最大ID+1

一.需求如下

在user表中,需要插入数据, 该数据的主键ID值为当前表最大ID+1, 比如: 当前表最大ID=977, 当插入数据: insert into(`date`, name) values('2026-04-28', '张三''), ('2026-04-28', '李四'')时,主键ID应该为978,979这样, 但现在进行插入时, 主键ID变化却是如下:

二.原因

造成上面情况的原因可能如下:

1.数据库自增主键的"预留区间"机制

许多现代应用框架或数据库中间件(如MyBatis-Plus的@TableId、或一些连接池)为了提高插入性能,采用了主键ID预取和缓存机制

  • 工作机制:应用启动时,或当本地缓存的ID用完时,会向数据库申请一个批次的ID(例如,一次申请100或200个ID范围),这个批次的起始值会远大于数据库中当前的最大值

  • 上面需求遇到的问题

    • 代码中查询到的"最新主键id=977",是数据库中实际已存在的最大值

    • 而新增时生成的1112,是应用服务本地缓存的一个ID批次的起始值,这个批次(例如1112-1211)是之前某个时刻提前从数据库申请来的,用完后才会申请下一个批次

  • 结果 :这导致了主键ID出现了一个**"跳跃"(从977直接跳到了1112),这是正常的设计,并非错误**,目的是避免每次插入都去数据库获取新ID,从而提高并发插入的效率

2.中间有数据被删除

  • 在ID为977之后,可能插入过很多条数据(ID达到了1111左右),但这些数据后来被物理删除了**,数据库的自增计数器并不会因为删除而回溯,会继续从当前最大值递增**

  • 通过查询条件(如时间、状态)看到的"最新"记录是977,但数据库中实际的最大自增ID已经是1111了

3.高并发插入与事务回滚

  • 在高并发场景下,多个事务可能同时申请了自增ID,如果某个申请了ID(例如978)的事务最终回滚 了,那么这个ID就会被"丢弃",自增计数器会继续增加,后续成功的事务就会获得像1112这样的ID,这会导致ID序列出现不连续的空洞

3.手动或程序指定了主键

  • 可能存在其他数据导入程序、数据修复脚本或特定的业务逻辑,在插入数据时手动指定了一个较大的主键ID(如1000),导致后续的自增ID从那个点开始计算

三.验证和排查

1.直接查询数据库自增当前值

  • 连接数据库,执行查询当前表自增主键下一个值的命令。例如,在MySQL中:

    复制代码
    SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '你的数据库名' AND TABLE_NAME = '你的表名';
  • 这个查询返回的数字,很可能就是 1112或更大,这能直接解释新增ID的起始点

2.审查代码中的主键生成策略

  • 检查实体类(Entity)中,主键字段的注解,是否使用了像 @TableId(type = IdType.AUTO)或其他如 ASSIGN_ID(分布式ID)等策略,如果是ASSIGN_ID,其生成算法(如雪花算法)本身就会产生不连续的大数字

3.检查数据删除和回滚记录

  • 查看是否有定期的数据清理任务

  • 检查数据库日志或应用日志,寻找大量插入失败或事务回滚的记录

四.解决办法

  • 1.确认实际最大ID

    SELECT MAX(id) FROM user;

  • 2.统一使用数据库自增,确保代码中主键策略配置正确

  • 3.检查并修复AUTO_INCREMENT值:

    复制代码
    ALTER TABLE user AUTO_INCREMENT = MAX(id) + 1;  -- 设置为当前最大ID+1
相关推荐
LabVIEW开发5 小时前
LabVIEW数据库事务操作
数据库·labview·labview知识·labview功能·labview程序
技术钱5 小时前
Flask-SQLAIchemy和Flask-Migrate扩展的配置与使用
数据库·python·flask
song8546011345 小时前
MYSQL优化器的主要的优化策略及其示例
数据库·mysql
杨浦老苏5 小时前
基于MongoDB Atlas的博客热榜
数据库·博客·blog·waline
Bert.Cai5 小时前
MySQL RAND()函数详解
数据库·mysql
怪我冷i5 小时前
多租户系统PostgreSQL
数据库·postgresql
发现你走远了5 小时前
极简后端环境搭建:一行 Docker 命令部署四大核心数据库(避坑 PG 18+)
数据库·docker·容器
北重楼016 小时前
如何取消一个挂起的 PostgreSQL 查询
数据库·postgresql
与数据交流的路上6 小时前
mysql参数-优化器 range_optimizer_max_mem_size 相关
数据库·mysql