在单个 INSERT 查询中插入多行会保证顺序自动递增主键吗?

Posted

技术标签:

【中文标题】在单个 INSERT 查询中插入多行会保证顺序自动递增主键吗?【英文标题】:Will inserting multiple rows within a single INSERT query guarantee sequential auto-increment primary keys? 【发布时间】:2020-03-20 13:05:29 【问题描述】:

假设我有这个简单的表:

CREATE TABLE some_table (
  id INT(11) PRIMARY KEY AUTOINCREMENT,
  name VARCHAR(20)
);

使用此 INSERT 语句:

INSERT INTO some_table (name) VALUES ("Foo"), ("Bar"), ("Buz");

结果给了我(例如):

fieldCount = 0
affectedRows = 3
insertId = 18
info = 'Records: 3  Duplicates: 0  Warnings: 0',
serverStatus = 2
warningStatus = 0

在执行 SELECT 语句时,我看到插入的第一行有 insertId = 18;是否保证后续插入的文档有id顺序?

换句话说,是否保证follow SELECT会产生以下行?

SELECT * FROM some_table WHERE id >= 18 LIMIT 3

id    | name
------+--------------
18    | Foo
19    | Bar
20    | Buz

如果这个结果不能保证,那么交易会保证吗?

如果一个事务不保证它,是否可以按顺序检索各个 id 值?

【问题讨论】:

以上断言完全不正确 这能回答你的问题吗? When I INSERT multiple rows into a mysql table, will the ids be increment by 1 everytime? mysql 做一些优化的同时,CPU 也可以做一些优化,所以如果你有高负载,order 和 id 不能连续。一个事务处理可以帮助解决这个问题,但是你锁定了表,这也没有帮助。您的表格不正确,id 必须是 autoimcrement 否则无济于事 【参考方案1】:

...单个查询会保证顺序自增主键吗?

没有。

数据库引擎将确保——但是——它们是不同的。首先,您为什么希望它们是连续的?

主键不应该性感或好看。主键是技术级别唯一的行标识符,通常对用户隐藏。它们不应显示在 UI 中或在任何报告中显示给最终用户。

如果您需要序列号,则意味着您可能希望在某处公开它们。不要为此使用主键。也许您应该为该特定目的创建一个辅助UNIQUE 列,具有漂亮的格式、可爱的编号等等。

【讨论】:

在编写 API 时,我正在寻找优化批量插入的方法,但由于 MySQL 不支持 RETURNING,并且只提供最后插入的 id(设置为实际插入的第一行) 插入了许多行,我正在考虑通过处理有限的结果而不是单独插入行来更新数据。我真的不在乎 id 是否是连续的,我只想获取它们的值。 我可能是错的,我记不太清楚了。当我从 JDBC (java) 使用 MySQL 时,getKeys() 方法将返回一个带有所有新创建的键的 ResultSet。但我需要检查一下。您使用什么语言/驱动程序来调用查询? 我正在使用带有 mysql2 模块的 Node.js。

以上是关于在单个 INSERT 查询中插入多行会保证顺序自动递增主键吗?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 多行插入是不是获取顺序自动增量 ID?

使用单个 INSERT 语句将多行插入到表中

第十九章:插入

php mysql_insert_id 在多行上?

在单个事务中插入多行时 Oracle 查询性能下降

MySQL ON DUPLICATE KEY UPDATE 在单个查询中插入多行