MySQL で parent child なレコード群の bulk insert
Published: 2023/3/14
問題
MySQL は、 PostgreSQL と違って (bulk) insert 文に対して、生成された id 群を返してくれない。 親子関係のあるレコード群を bulk insert していきたい場合に問題になるので、これはどうやって実現されているのか、調べてみた。
なお、ここでいう bulk insert とは、
INSERT INTO `users`(`name`, `age`) VALUES (('John', 28), ('Adam', 20));
のように一つの insert 文で複数レコードを挿入すること。
方法: LAST_INSERT_ID() を使う
MySQL には LAST_INSERT_ID()
という関数があり、この関数は直前に実行された INSERT 文により生成された、最初の auto increment 値を返す。
これは接続ごとに保持される値であり、他の接続の影響を受けないため、同時実行の整合性を気にせずに利用できる。
How can I Insert many rows into a MySQL table and return the new IDs?
Normally I can insert a row into a MySQL table and get the last_insert_id back. Now, though, I want to bulk insert many rows into the table and get back an array of IDs. Does anyone know how I can do
stackoverflow.com

また、上記のページによれば、 innodb_autoinc_lock_mode
の値を適切に設定することにより、 bulk insert の際に生成される auto increment の id たちを連番にできる、とのこと。
この二つを組み合わせて、親(parent)のテーブルから insert し、 LAST_INSERT_ID()
によって先頭のレコードの id を特定し、 ROW_COUNT()
で更新された行数を取得することで、実際に insert されたレコードたちの id を計算できる。
Tags: mysql
関連記事
ローカルで mysql をサクッと立てたい時に使うコマンド
2023/10/26
ARIES と fuzzy check pointing
2021/6/1
MySQL で json 配列の要素一つ一つをレコードとする
2019/3/2