【发布时间】:2023-03-14 17:20:01
【问题描述】:
如果我有如下查询:
INSERT INTO table (col1,col2,col3) VALUES
('col1_value_1', 'col2_value_1', 'col3_value_1'),
('col1_value_2', 'col2_value_2', 'col3_value_2'),
('col1_value_3', 'col2_value_3', 'col3_value_3');
假设我有一个表,其中最后一个 id PRIMARY_KEY AUTO_INCREMENT 值是 56,那么这个插入查询是否总是会创建 3 个 ID 为 57, 58, 59 的记录。这个操作是原子的吗?
或者,如果另一个查询写入同一个表,ids 是否不能始终递增 1?
感谢关注!
编辑:请阅读以下内容,因为我可能不太清楚。
当然AUTO_INCREMENT 安全地递增一,我知道。
重点是:
假设我有一个名为table 的表格:
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
|____________________________________|
如果我知道运行查询:
INSERT INTO table (col1,col2) VALUES
('some val', 'some other val'),
('some val', 'some other val'),
('some val', 'some other val')
我最终会得到下表:
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
| 7 | "some val" | "some other val" |
| 8 | "some val" | "some other val" |
| 9 | "some val" | "some other val" |
|____________________________________|
这里没什么好说的。但如果我和另一个人同时运行相同的查询,这些查询是原子吗?这意味着我们将总是最终得到:
1)
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
| 7 | "some val" | "some other val" |<-- My 1st inserted record
| 8 | "some val" | "some other val" |<-- My 2nd inserted record
| 9 | "some val" | "some other val" |<-- My 3rd inserted record
| 10 | "some val" | "some other val" |<-- Another guy's 1st inserted record
| 11 | "some val" | "some other val" |<-- Another guy's 2nd inserted record
| 12 | "some val" | "some other val" |<-- Another guy's 3rd inserted record
|____________________________________|
或与:
2)
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
| 7 | "some val" | "some other val" |<-- Another guy's 1st inserted record
| 8 | "some val" | "some other val" |<-- Another guy's 2nd inserted record
| 9 | "some val" | "some other val" |<-- Another guy's 3rd inserted record
| 10 | "some val" | "some other val" |<-- My 1st inserted record
| 11 | "some val" | "some other val" |<-- My 2nd inserted record
| 12 | "some val" | "some other val" |<-- My 3rd inserted record
|____________________________________|
取决于两个 MySQL 的哪个查询先调度。
或者是否也会出现以下异常?:
3)
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
| 7 | "some val" | "some other val" |<-- My 1st inserted record
| 8 | "some val" | "some other val" |<-- My 2nd inserted record
| 9 | "some val" | "some other val" |<-- Another guy's 1st inserted record - WTF???
| 10 | "some val" | "some other val" |<-- My 3rd inserted record
| 11 | "some val" | "some other val" |<-- Another guy's 2nd inserted record
| 12 | "some val" | "some other val" |<-- Another guy's 3rd inserted record
|____________________________________|
或者是这样的:
4)
___________________________________
| id | col1 | col2 |
-------------------------------------
| 1 | "some val" | "some other val" |
| 2 | "some val" | "some other val" |
| 3 | "some val" | "some other val" |
| 4 | "some val" | "some other val" |
| 5 | "some val" | "some other val" |
| 6 | "some val" | "some other val" |
| 7 | "some val" | "some other val" |<-- Another guy's 1st inserted record
| 8 | "some val" | "some other val" |<-- My 1st inserted record - WTF???
| 9 | "some val" | "some other val" |<-- Another guy's 2nd inserted record
| 10 | "some val" | "some other val" |<-- My 2nd inserted record - WTF^2???
| 11 | "some val" | "some other val" |<-- Another guy's 3rd inserted record
| 12 | "some val" | "some other val" |<-- My 3rd inserted record - WTF^3???
|____________________________________|
或任何其他组合!= 3) 和 4)?
我认为 1) 和 2) 是原子的。是否总是保证我会总是以 1) 或 2) 结束并且永远不会 以 3) 或 4) 或任何其他组合结束?如果是的话(我总是以1) 或2) 结尾),对于MyISAM 和InnoDB?
如果我这样做 SELECT LAST_INSERT_ID(); 和例如我得到7,这是否自动意味着带有id 8 和9 的行也是由我的查询而不是由其他人的查询插入的?
【问题讨论】:
-
是的,id 会一直递增。
-
@JörnBuitink 请检查我的编辑。
-
LAST_INSERT_ID()在连接的基础上运行。其他人和你不会在同一个连接中做事情。因此,您是孤立的,您将收到自己操作的最后一个 id。 -
@Mjh 是的,我知道我和其他用户将收到我们自己操作的最后一个 id,并且会有所不同。这不是重点。关键是:给定我的批量
INSERT查询,其中插入例如10 条记录,我执行它然后我得到LAST_INSERT_ID()。如果例如LAST_INSERT_ID() = 71总是意味着我添加的 10 条记录的 id 为71、72、73、74、75、76、77,78,79,80? -
它没有必须,但因为它是批量插入,所以是的。
标签: mysql last-insert-id