关于 MySQL insert 和自增 ID 的奇怪事件

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 关于 MySQL insert 和自增 ID 的奇怪事件

你好,我是yes。

上周五,我的读者向我提了个问题,这个问题既熟悉又生僻,还是挺有意思的,所以我在这里分享一下。

首先有建立一张表

CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

表没什么花头,主键是 ID,然后是自增的。

此时执行一条插入语句:

insert into t (id,c,d) values (1,1,1),(null,2,2),(7,7,7),(null,4,4);

语句中既有指定的 ID,又有让 MySQL 自己计算的自增 ID。

然后此时,再执行一条sql

insert into t (id,c,d) values (null,9,9);

你觉得这条插入的 ID 应该是几?

你肯定以为是 9 ,实际上这条新纪录的 ID 是 10。

乍一看,不对啊,第一条插入语句的最后一个记录是 (null,4,4),它的 ID 是 8 ,那为什么紧接着的后面一个插入自增 ID 直接变到了 10 而不是 9 ?

为什么中间空了一个 ID?

讲实话,我也不知道,于是我去官网寻寻觅觅,果然皇天不负有心人,嘻嘻。


image.png


这种一条语句里面,即包含指定 ID 又有自增 ID 的叫做Mixed-mode inserts

然后关于自增 ID 的模式,又分为三种,我在之前的文章分析过:


image.png


image.png


简单的来了个机翻:

例外情况是“混合模式插入”,其中用户为多行“简单插入”中的某些(但不是全部)行提供 AUTO_INCREMENT 列的显式值。 对于此类插入,InnoDB 分配的自动增量值多于要插入的行数。 但是,所有自动分配的值都是连续生成的(因此高于)由最近执行的前一条语句生成的自动增量值。 “多余”的数字丢失

好了,破案了,官网上已经写的很清楚了,这样的插入在innodb_autoinc_lock_mode = 1的情况下,InnoDB 就是会分配多余插入行数的 ID 数,而多出来的 ID 就被丢弃了。

所以后面的插入看起来就和前面断掉了,搞得像一部分 ID 莫名其妙被吃了一样。

那为什么会 InnoDB 要这样实现呢?

如果想具体知道这个问题,那肯定得看源码了,那成本就太大了。

我盲猜猜,你一条插入里面即自己设定了 ID,又让 InnoDB 计算自增 ID,在代码实现上估计有点难度,想要做到完美的自增 ID 序列估计成本有点大。

简单来说就是得不偿失,自增  ID 这么多,少一两个不要紧,所以就简单实现,一次多准备点,这样插入就不会出错啦~


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8天前
|
存储 关系型数据库 MySQL
MySQL 8.0特性-自增变量的持久化
【11月更文挑战第8天】在 MySQL 8.0 之前,自增变量(`AUTO_INCREMENT`)的行为在服务器重启后可能会发生变化,导致意外结果。MySQL 8.0 引入了自增变量的持久化特性,将其信息存储在数据字典中,确保重启后的一致性。这提高了开发和管理的稳定性,减少了主键冲突和数据不一致的风险。默认情况下,MySQL 8.0 启用了这一特性,但在升级时需注意行为变化。
|
18天前
|
NoSQL 关系型数据库 MySQL
2024Mysql And Redis基础与进阶操作系列(4-2)作者——LJS[含MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法]
24MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法(4-2) 学不会你来砍我!!!
|
3月前
|
关系型数据库 MySQL
MySQL自增ID用完会怎样?
MySQL自增ID用完会怎样?
|
8天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
29 3
|
8天前
|
存储 监控 关系型数据库
MySQL自增ID耗尽解决方案:应对策略与实践技巧
在MySQL数据库中,自增ID(AUTO_INCREMENT)是一种特殊的属性,用于自动为新插入的行生成唯一的标识符。然而,当自增ID达到其最大值时,会发生什么?又该如何解决?本文将探讨MySQL自增ID耗尽的问题,并提供一些实用的解决方案。
15 1
|
1月前
|
SQL 关系型数据库 MySQL
MySQL设置表自增步长
MySQL设置表自增步长
79 0
|
3月前
|
存储 自然语言处理 关系型数据库
MySQL全文索引源码剖析之Insert语句执行过程
【8月更文挑战第17天】在MySQL中,处理含全文索引的`INSERT`语句涉及多步骤。首先进行语法解析确认语句结构无误;接着语义分析检查数据是否符合表结构及约束。随后存储引擎执行插入操作,若涉及全文索引则进行分词处理,并更新倒排索引结构。此外,事务管理确保了操作的完整性和一致性。通过示例创建含全文索引的表并插入数据,可见MySQL如何高效地处理此类操作,有助于优化数据库性能和提升全文搜索效果。
|
3月前
|
关系型数据库 MySQL
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
254 2
|
3月前
|
存储 关系型数据库 MySQL
在 MySQL 中使用 Insert Into Select
【8月更文挑战第11天】
530 0
在 MySQL 中使用 Insert Into Select
|
4月前
|
运维 关系型数据库 MySQL
实时计算 Flink版产品使用问题之在处理MySQL表新增数据记录时,没有正确触发变更事件,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。