【问题标题】:Auto increment id field is not add 1 after executing MySQL bulk insert query执行 MySQL 批量插入查询后自动递增 id 字段不加 1
【发布时间】:2020-07-17 14:23:42
【问题描述】:

在测试我制作的用户表时,我发现了一些奇怪的东西。 在执行如下所示批量插入多个用户的查询后添加单行时,id 字段的值增加了 2 而不是 1。

批量插入查询

INSERT INTO USER_TB (ID,NICKNAME,USER_LV,EXP) VALUES (1,'test1',1,0)
,(NULL,'test2',1,0)
,(NULL,'test3',1,0)
,(NULL,'test4',1,0);

单行插入查询

INSERT INTO USER_TB (ID,NICKNAME,USER_LV,EXP) VALUES (NULL,'test5',1,0);

预期结果

实际结果

如果您不强制批量插入查询中的 id 字段,它可以正常工作。 但我想知道为什么会这样。

提前致谢。

【问题讨论】:

  • 这是不可重现的,请参阅dbfiddle.uk/…,只要您不删除行,它应该始终为您提供下一个编号,这可能会发生,只是“订单”可能会搞砸跨度>
  • 抱歉,您能详细说明一下吗?
  • 我无法重现您的问题,请参阅小提琴,因此根据我的经验,不会发生跳过,没有像 删除 行这样的用户操作。当然,当您拥有一台具有大量流量和不同实体 mysql 或处理器的重型服务器时,可以重新排列代码,我可以想到一个数字已跳过的问题,但批量插入不是原因。也就是说,正如我提到的,有些实体可以重新排列代码,即使有序列号,test1 也可能在 test 3 之后。
  • 我在你的小提琴中重现了这个问题。见dbfiddle.uk/…

标签: mysql


【解决方案1】:

其实挺难的

CREATE TABLE USER_TB (ID INT Auto_inCREMENT Primary KEY,
NICKNAME varchar(50)
,USER_LV INT ,
EXP BIGINT)
INSERT INTO USER_TB (ID,NICKNAME,USER_LV,EXP) VALUES (NULL,'test1',1,0),(NULL,'test2',1,0),(NULL,'test3',1,0),(NULL,'test4',1,0),
(NULL,'test5',1,0),(NULL,'test6',1,0),(NULL,'test7',1,0),(NULL,'test8',1,0),
(NULL,'test9',1,0),(NULL,'test10',1,0),(NULL,'test11',1,0),(NULL,'test12',1,0);
SELECT LAST_INSERT_ID(); 
| LAST_INSERT_ID() | | ---------------: | | 1 |
INSERT INTO USER_TB VALUES (NULL,'test13',1,0),(NULL,'test14',1,0)
SELECT LAST_INSERT_ID(); 
| LAST_INSERT_ID() | | ---------------: | | 13 |
SELECT * FROM USER_TB;
身份证 |昵称 | USER_LV |经验值 -: | :------- | ------: | --: 1 |测试1 | 1 | 0 2 |测试2 | 1 | 0 3 |测试3 | 1 | 0 4 |测试4 | 1 | 0 5 |测试5 | 1 | 0 6 |测试6 | 1 | 0 7 |测试7 | 1 | 0 8 |测试8 | 1 | 0 9 |测试9 | 1 | 0 10 |测试10 | 1 | 0 11 |测试11 | 1 | 0 12 |测试12 | 1 | 0 13 |测试13 | 1 | 0 14 |测试14 | 1 | 0

db小提琴here

你的插入有什么不同的是第一个

(1,'test1',1,0)

所以 mysql 计数 +1 所以它似乎跳过了 1 个数字

如果我把它作为第一个插入

(2,'test1',1,0)

它从 2 开始,在第一个 INSERT 结束时“跳过”2,因为在他的内部计数器中,他有 14 (12 + 2)

CREATE TABLE USER_TB (ID INT Auto_inCREMENT Primary KEY,
NICKNAME varchar(50)
,USER_LV INT ,
EXP BIGINT)
INSERT INTO USER_TB (ID,NICKNAME,USER_LV,EXP) VALUES (2,'test1',1,0),(NULL,'test2',1,0),(NULL,'test3',1,0),(NULL,'test4',1,0),
(NULL,'test5',1,0),(NULL,'test6',1,0),(NULL,'test7',1,0),(NULL,'test8',1,0),
(NULL,'test9',1,0),(NULL,'test10',1,0),(NULL,'test11',1,0),(NULL,'test12',1,0);
SELECT LAST_INSERT_ID(); 
| LAST_INSERT_ID() | | ---------------: | | 3 |
INSERT INTO USER_TB VALUES (NULL,'test13',1,0),(NULL,'test14',1,0)
SELECT LAST_INSERT_ID(); 
| LAST_INSERT_ID() | | ---------------: | | 15 |
SELECT * FROM USER_TB;
身份证 |昵称 | USER_LV |经验值 -: | :------- | ------: | --: 2 |测试1 | 1 | 0 3 |测试2 | 1 | 0 4 |测试3 | 1 | 0 5 |测试4 | 1 | 0 6 |测试5 | 1 | 0 7 |测试6 | 1 | 0 8 |测试7 | 1 | 0 9 |测试8 | 1 | 0 10 |测试9 | 1 | 0 11 |测试10 | 1 | 0 12 |测试11 | 1 | 0 13 |测试12 | 1 | 0 15 |测试13 | 1 | 0 16 |测试14 | 1 | 0

db小提琴here

所以从(NULL,'test1',1,0) 开始,一切都按预期进行

【讨论】:

  • 自增值是由内部计数器值决定的吗?以及Internal counter和LAST_INSERT_ID是什么关系?
猜你喜欢
  • 1970-01-01
  • 2019-04-28
  • 2014-08-03
  • 1970-01-01
  • 2019-07-12
  • 2013-04-25
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
相关资源
最近更新 更多