mysql - MySQL INSERT .. SELECT 语句的 auto_increment 字段值顺序是什么

标签 mysql sql-order-by auto-increment bulkinsert

假设我们有下一张 table :

CREATE TABLE test_insert_order (
  id INT(11) NOT NULL AUTO_INCREMENT,
  parent_id INT(11) NOT NULL,
  name VARCHAR(20),
  PRIMARY KEY (id)
);

一些数据如

INSERT INTO test_insert_order (parent_id, name) VALUES (1, 'a'),(1, 'b'),(1,'c'),(2,'b'),(2,'d'),(2,'a'),(3,'d'),(3,'a'),(4,'aa'),(5,'bb'),(6,'a'),(3,'a'),(1,'d'),(2,'c');

如果我们这样做

INSERT INTO test_insert_order (parent_id, name) SELECT 7, `name` FROM test_insert_order WHERE parent_id = 2 ORDER BY id;

我们可以假设新的 auto_generated id 与 select 结果中的 id 的顺序相同吗

SELECT id, 7, `name` FROM test_insert_order WHERE parent_id = 2 ORDER BY id;

因此在下一个查询结果中,a.name 将始终匹配 b.name

SET @i:=0;set @j:=0;
SELECT a.id, a.parent_id, a.name, a.order_id, b.id, b.parent_id, b.name, b.order_id FROM
  (SELECT *, @j:=@j+1 as order_id FROM test_insert_order WHERE parent_id = 2 ORDER BY id) a,
  (SELECT *, @i:=@i+1 as order_id FROM test_insert_order WHERE parent_id = 7 ORDER BY id) b
WHERE a.order_id = b.order_id;

我用并发线程做了一些测试,它总是正确的。但是我在 MySQL 文档中找不到任何关于这种情况的信息。

更新: 我猜这在一些集群解决方案中可能不是真的,当一些实例有自己的自动增量值模式,并且一个落后并且查询执行以某种方式分布在它们之间。但是我没有环境来检查这个。

最佳答案

经过更多研究后,我将回答我自己的问题。

我想在大多数情况下这都是正确的,但我能够找到该算法可能导致问题的情况。首先是在我对有关集群解决方案的问题的更新中提到的。其次,我可以想象当表在 id - auto_increment 字段(最初从 1000000 开始而不是 0)中有间隙并且在执行插入语句期间 auto_increment 值手动更改为较低值的情况。所以这将打破 auto_increment 模式。 我建议改为使用我们可以预测唯一性的一些有意义的字段的顺序。如果没有,则说明与刚刚插入的2条相同的记录没有区别使用。

关于标题的问题。单个 MySQL 实例中的单个批量插入中的 Auto_increment 值通常会按升序排列,但有时会因 auto_increment 值更改为较低而中断。在集群解决方案上,它取决于集群的实现,而且很可能也不可预测。

关于mysql - MySQL INSERT .. SELECT 语句的 auto_increment 字段值顺序是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609898/

相关文章:

php - mySQL自增问题: Duplicate entry '4294967295' for key 1

在同一查询中使用 group by 和 order by 时,mysql 查询速度会变慢

SQL Server 通过预定义顺序进行排序

mysql - 停止 MySQL 在 UNIQUE 约束中容忍多个 NULL

MySQL 方法 : Large self-joins to set values?

mysql - 如果第一列是唯一的,是否会检查 ORDER BY 的第二列?

sql - 优化 Hibernate Sequence ID 生成

c# - 如何在 Documentdb 中创建一个自动递增的列

mysql - 有没有办法使用 RMySQL 调用存储过程?

mysql - 我正在尝试创建一个只有两个外键的表