繁体   English   中英

计算多行插入语句的插入 ID 的可靠性

[英]Reliability of computing insert ids of a multi-row insert statement

我在一条语句中进行多次插入,例如:

INSERT INTO table (foo) VALUES ('aaa'), ('bbb'), ('ccc')

当我尝试获取最后一个插入 ID 时,MySQL (PDO) 仅提供第一个插入 ID。

因为我知道我插入了多少项目(上面示例中的三个项目),只要INSERT作为事务完成,手动计算插入的 ids 是否可靠?

例如,如果 MySQL 返回的第一个插入 ID 是5 ,我可以安全地假设上述INSERT示例的插入 ID 是567吗? 或者,如果另一个用户同时插入,是否仍然存在重叠的可能性,即使它们是作为事务完成的?


建议的重复问题虽然相似,但没有明确回答我的问题。 那里接受的答案只说只给出第一个插入 id 是预期的行为,我同意,但我的问题是关于手动计算方法的可靠性。 那里的评论部分也看起来很有趣。

MySQL 的 JDBC 连接器的代码依赖于 id 的批次是连续的。

MySQL 协议只返回生成的第一个 id。 但是 JDBC 接口要求连接器实现一个返回所有生成的 id 的方法。 所以它必须假设第一个后面的 id 是连续值。

但每条规则都有例外。

  • 如果您执行“混合模式”的 INSERT,则该假设无效。 这意味着您执行多行 INSERT,其中一些行指定一个值,但其他行期望生成一个新的 id。

  • 如果执行“混合模式”或“批量”插入(后者类似于 INSERT...SELECT 或 LOAD DATA,或行数事先未知的任何其他时间),并且innodb_autoinc_lock_mode=2 (“交错”)并且在另一个 session 中存在任何类型的并发 INSERT,那么您的 INSERT 的 id 集可能不是连续的。

要了解有关这些问题的更多详细信息,请仔细阅读https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

我宁愿不做假设。

我插入多行然后立即需要它们的 id 的主要地方是在“规范化”一堆值以便我可以改用 id 时。

这样做时:

  1. 从包含要规范化的字符串的临时表开始,
  2. 使用INSERT...SELECT DISTINCT...将它们放入 id:name 查找表
  3. 使用UPDATE.. JOIN.. SET temp.id = norm.id WHERE temp.name = norm.name

它高效,多线程安全等更多细节: http://mysql.rjweb.org/doc.php/staging_table#normalization

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM