[英]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 是5
、 6
、 7
吗? 或者,如果另一个用户同时插入,是否仍然存在重叠的可能性,即使它们是作为事务完成的?
建议的重复问题虽然相似,但没有明确回答我的问题。 那里接受的答案只说只给出第一个插入 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 时。
这样做时:
INSERT...SELECT DISTINCT...
将它们放入 id:name 查找表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.