Py学习  »  DATABASE

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

码小辫 • 2 年前 • 257 次点击  

在这里分享一个问题。

首先有建立一张表

CREATE TABLE `t` (
  `id` int(11NOT NULL AUTO_INCREMENT,
  `c` int(11DEFAULT NULL,
  `d` int(11DEFAULT 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?

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

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

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

所以默认值是 1。

然后默认值是 1 再加上这次的插入是Mixed-mode inserts,就发生了点火花。

简单的来了个机翻:

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

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

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

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

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

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

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

好了,官网链接:https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

这次短平快到此结束。

-END-

关注视频号,参与留言送书活动

↓↓↓↓

一个认真分享的小编

前沿技术 /名企内推 /干货分享

商务合作:dot3721
长按左侧二维码添加

点分享

点点赞

点在看


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/119039
 
257 次点击