简体   繁体   中英

Reliability of computing insert ids of a multi-row insert statement

I am doing multiple inserts in one statement eg:

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

When I try to get the last insert id, MySQL (PDO) only gives the first insert id.

Since I know how many items I inserted (three items from the example above), is it reliable to manually compute the inserted ids as long as the INSERT is done as a transaction?

Eg, if the first insert id that MySQL returns is 5 , can I safely assume that the insert ids of the above INSERT example is 5 , 6 , 7 ? Or is there still a possibility of overlap if another user inserts at the same time, even if they were done as a transaction?


The suggested duplicate question , while similar, does not clearly answer my question. The accepted answer there only says it is expected behavior that only the first insert id is given, which I agree, but my question here is about how reliable is the method of the manual computation. The comments section there also looks anecdotal.

The code for MySQL's JDBC connector relies on the batch of id's being consecutive.

The MySQL protocol only returns the first id generated. But the JDBC interface requires the connector to implement a method that returns all the id's generated. So it must make an assumption that the id's following the first are consecutive values.

But there's are exceptions to every rule.

  • If you execute an INSERT that is "mixed-mode" then the assumption is not valid. This means you do a multi-row INSERT where some rows specify a value but other rows expect a new id to be generated.

  • If you execute an INSERT that is "mixed-mode" or "bulk" (the latter is like INSERT...SELECT or LOAD DATA, or any other time where the number of rows is not known in advance), and innodb_autoinc_lock_mode=2 ("interleaved") and there are concurrent INSERTs of any kind in another session, then the set of id's for your INSERT might not be consecutive.

To understand more detail about these issues, read https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html carefully.

I prefer not to make assumptions.

The main place where I have inserted multiple rows, then immediately needed their ids, was when "normalizing" a bunch of values so I can use ids instead.

When doing that:

  1. Start with a temp table that contains the strings being normalized,
  2. Use INSERT...SELECT DISTINCT... to put them into the id:name lookup table
  3. Use UPDATE.. JOIN.. SET temp.id = norm.id WHERE temp.name = norm.name .

It's efficient, multi-thread-safe, etc. More details: http://mysql.rjweb.org/doc.php/staging_table#normalization

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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