【问题标题】:What is auto_increment fields values order for MySQL INSERT .. SELECT statementMySQL INSERT .. SELECT 语句的 auto_increment 字段值顺序是什么
【发布时间】:2020-02-24 20:08:08
【问题描述】:

假设我们有下一张桌子:

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;

我们可以假设新的自动生成的 id 将与选择结果中的 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 文档中找不到关于这种情况的任何内容。

更新: 我想这在某些集群解决方案中可能不是真的,因为一些实例具有自己的自动增量值模式,并且一个实例落后并且查询执行在某些情况下分布。但是我没有环境来检查这个。

【问题讨论】:

  • 基于this accepted answer,插入的行顺序与选择查询中遇到的行顺序相匹配。
  • @TimBiegeleisen 所以你说的是 ``` INSERT .. SELECT .. ORDER BY...; ``` 等价于 ``` INSERT ... SELECT .... ORDER BY ... LIMIT 0, 1; INSERT ... SELECT .... ORDER BY ... LIMIT 1,1 ; ... 插入 ... 选择 .... ORDER BY ... 限制 n-1,1 ; ``` 你有任何关于 MySQL 文档的注释吗?
  • 我不知道文档参考,但我从来不知道还有什么是真实的。
  • @TimBiegeleisen 我只是担心,因为我发现许多堆栈溢出答案表明 order by 对于 INSERT ... SELECT 语句无关紧要,但没有一个与 auto_increment 字段有关。无论如何感谢您的评论。
  • 是的,这很重要,但话说回来,你已经在使用ORDER BY,所以我懒得对此发表评论。

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


【解决方案1】:

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

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

关于标题中的问题。单个 MySQL 实例中的单个批量插入中的 Auto_increment 值通常会按递增顺序排列,但在某些情况下,它可能会因 auto_increment 值更改为较低而中断。在集群解决方案上,它取决于集群实现,而且很可能也无法预测。

【讨论】:

    猜你喜欢
    • 2013-07-20
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2010-12-29
    相关资源
    最近更新 更多