MySQL在多行插入中的AUTO_INCREMENT行为

10

我认为我的问题的答案很明显,但由于我找不到任何支持它的文档,所以我认为值得问一下。至少为了记录。

众所周知,AUTO_INCREMENT字段在每次执行INSERT语句时递增。并且可以通过LAST_INSERT_ID()函数检索其值。在MySQL手册中还提到,对于多行插入,LAST_INSERT_ID()将返回插入行的第一个ID。我认为这是一个好主意(非常有用)。

那么问题来了:

在带有多行的INSERT IGNORE INTO语句中,我可以假设AUTO_INCREMENT字段的插入ID始终是顺序的吗?请记住,由于IGNORE修饰符和MySQL服务器的多用户特性,可能会发生不同的情况。

谢谢。

1个回答

10
不,你不能假定ID是顺序的。在复制的多主设置中,ID不顺序的一个情况是存在的。例如,如果这样的设置有两个服务器,则一个服务器只会生成偶数自动ID,另一个服务器则只会生成奇数ID(请记住这只是一个例子)。
然而,如果你的设置不是这样的,那么就可以了。至少在InnoDB中,插入操作是原子性的,并且当针对同一表时是排队的,因此来自两个不同INSERT的ID不会交错。(尽管它没有被记录在文档中,所以依赖它有点冒险)
我如何测试IGNORE INSERT ID的生成:
mysql> CREATE TABLE  `ignoreinsert` (
    ->   `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
    ->   `uq` int(10) unsigned NOT NULL,
    ->   PRIMARY KEY (`ID`),
    ->   UNIQUE KEY `uq` (`uq`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.19 sec)

mysql> INSERT INTO ignoreinsert VALUES (null,1),(null,2);
Query OK, 2 rows affected (0.10 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM ignoreinsert;
+----+----+
| ID | uq |
+----+----+
|  1 |  1 |
|  2 |  2 |
+----+----+
2 rows in set (0.00 sec)

mysql> INSERT IGNORE INTO ignoreinsert VALUES (null,3),(null,1),(null,4),(null,2),(null,5);
Query OK, 3 rows affected (0.08 sec)
Records: 5  Duplicates: 2  Warnings: 0

mysql> SELECT * FROM ignoreinsert;
+----+----+
| ID | uq |
+----+----+
|  1 |  1 |
|  2 |  2 |
|  3 |  3 |
|  4 |  4 |
|  5 |  5 |
+----+----+
5 rows in set (0.00 sec)

IGNORE修饰符怎么样?即使插入了重复行,计数器是否会继续增加?我问这个问题是因为我发现在没有IGNORE修饰符的单行INSERT语句中,当出现错误时,计数器会增加,即使该行未被插入! - Mehran
1
Mehran Ziadloo:我刚刚进行了一次检查以确保ID是连续的。 - Mchl
我的错误,使用IGNORE修饰符不会增加计数器。这是针对将_重复键_错误转换为警告的行。 - Mehran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接