【问题标题】:MySQL INSERT .. UPDATE breaks AUTO_INCREMENT?MySQL INSERT .. UPDATE 打破了 AUTO_INCREMENT?
【发布时间】:2011-06-18 12:27:51
【问题描述】:

有以下两个表:

create table lol(id int auto_increment, data int, primary key id(id));
create table lol2(id int auto_increment, data int, primary key id(id));

插入一些值:

insert into lol2 (data) values (1),(2),(3),(4);

现在使用 select 插入:

insert into lol (data) select data from lol2;

再做一次:

insert into lol (data) select data from lol2;

现在看表:

select * from lol;

我收到:

+----+------+
| id | data |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  8 |    1 |
|  9 |    2 |
| 10 |    3 |
| 11 |    4 |
+----+------+

我对 4 和 8 之间的差距感到困惑...是什么原因造成的,我该怎么做才能没有差距?非常感谢!

【问题讨论】:

  • innodb_autoinc_lock_mode 的值是多少?
  • 尝试删除表并再次运行查询,它不应该这样做。当我尝试时,我有 1 到 8 个 ID。一个查询可能会失败一次并增加 ID。自动增量不是取最大数加 1,它存储在元表中。因此,如果有任何失败,自动增量将增加,但您将没有记录 - 您最终会出现差距。
  • 鉴于丢失了 4 个密钥,这似乎是事务回滚,并且自动编号没有被重用。
  • 对不起,我如何获得 innodb_autoinc_lock_mode 的值?
  • 我明白了。 bugs.mysql.com/bug.php?id=61058这是一个已报告的错误。

标签: mysql insert auto-increment


【解决方案1】:

auto_increment 不保证 ID 列中的增量为 1。它不能,因为一旦你处理并行事务,它就会中断:

BEGIN                                  BEGIN
  INSERT INTO lol VALUES(...)            INSERT INTO lol VALUES(..)   
  ...                                    ...
COMMIT                                 ROLLBACK

数据库应该分配什么ID?它无法提前知道哪个事务会成功,哪个事务会回滚。

如果您需要对记录进行连续编号,则可以使用返回该编号的查询;例如

SELECT COUNT(*) as position, lol.data FROM lol 
INNER JOIN lol2 ON lol.id < lol2.id 
GROUP BY lol.id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2023-03-31
    • 2017-09-01
    • 2014-09-29
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多