MySQL 在多行插入中的 AUTO_INCRMENT 行为

发布于 2024-11-27 12:25:39 字数 498 浏览 2 评论 0原文

我认为我的问题的答案是显而易见的,但由于我找不到任何文档来支持它,我认为值得一问。至少有记录。

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

所以我的问题是:

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

谢谢。

I think the answer to my question is obvious but since I could not find any documentation to support it, I thought it's worth asking. At least for the record.

As we all know AUTO_INCREMENT fields are incremented each time an INSERT statement is executed. And its value can be retrieved by LAST_INSERT_ID() function. It is also mentioned in MySQL's Manual that with multiple-row inserts, LAST_INSERT_ID() will return the first ID of the inserted rows. Which I think is a good idea (really useful).

So here goes my question:

Can I assume in an INSERT IGNORE INTO statement with multiple-rows, the inserted IDs of an AUTO_INCREMENT field will always be sequential? Keep in mind that due to IGNORE modifier and the multi-user nature of MySQL server, different scenarios might happen.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柏拉图鍀咏恒 2024-12-04 12:25:39

不,你不能这样假设。 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)

No you can not assume that. One scenario where ID's would not be sequential is in replicated multi-master setup. If for example two servers exist in such setup, one will only generate even auto IDs, and the other only odd IDs (keep in mind it's just an example).

However if your setup is not something like that, then yes. At least in InnoDB inserts are atomic and are queued when targetting same table, so ID's from two different INSERT's will not interlace. (it's not documented though, so relying on it is... a bit risky)


How I tested IGNORE INSERT ID generation:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文