MySQLのReplace構文はAUTO_INCREMENTカラムがサロゲートキーの場合、利用しない方が良い
MySQL徹底入門 第4版の第3章を読み、MySQLにReplace構文があることを学んだのでアウトプットしておく。
Replace構文 は、INSERTと似た挙動をする。
しかし、UNIQUE インデックスがついている時、古い行を削除し新しい行をInsertするという注意するべき挙動がある。
この挙動は、サロゲートキーを設定している時に問題になる。以下は、実験コードだ。
replace into user (name, email) values ("hoge", "taro@example.com");
を実行した時、id
が 11から12になっている。
mysql> create table user (id int auto_increment primary key, name varchar(255) not null, email varchar(255) not null unique key); mysql> INSERT INTO `user` (`name`,`email`) VALUES ("Alec","nostra.per.inceptos@aliquet.net"),("Myles","libero.mauris.aliquam@tristiquepharetra.edu"),("Damian","dictum@necluctusfelis.co.uk"),("Baker","Curabitur.consequat@enimNunc.edu"),("Alvin","eget@magnaPhasellus.org"),("Fulton","adipiscing@feugiatplaceratvelit.com"),("Malachi","ultrices.Duis@est.org"),("Vernon","arcu@porttitor.edu"),("Carl","Etiam.ligula.tortor@auctor.ca"),("Gray","Suspendisse@diamdictum.ca"); mysql> replace into user (email) values ("hoge@example.com"); mysql> select * from user; +----+---------+---------------------------------------------+ | id | name | email | +----+---------+---------------------------------------------+ | 1 | Alec | nostra.per.inceptos@aliquet.net | | 2 | Myles | libero.mauris.aliquam@tristiquepharetra.edu | | 3 | Damian | dictum@necluctusfelis.co.uk | | 4 | Baker | Curabitur.consequat@enimNunc.edu | | 5 | Alvin | eget@magnaPhasellus.org | | 6 | Fulton | adipiscing@feugiatplaceratvelit.com | | 7 | Malachi | ultrices.Duis@est.org | | 8 | Vernon | arcu@porttitor.edu | | 9 | Carl | Etiam.ligula.tortor@auctor.ca | | 10 | Gray | Suspendisse@diamdictum.ca | | 11 | taro | taro@example.com | +----+---------+---------------------------------------------+ mysql> replace into user (name, email) values ("hoge", "taro@example.com"); mysql> select * from user; +----+---------+---------------------------------------------+ | id | name | email | +----+---------+---------------------------------------------+ | 1 | Alec | nostra.per.inceptos@aliquet.net | | 2 | Myles | libero.mauris.aliquam@tristiquepharetra.edu | | 3 | Damian | dictum@necluctusfelis.co.uk | | 4 | Baker | Curabitur.consequat@enimNunc.edu | | 5 | Alvin | eget@magnaPhasellus.org | | 6 | Fulton | adipiscing@feugiatplaceratvelit.com | | 7 | Malachi | ultrices.Duis@est.org | | 8 | Vernon | arcu@porttitor.edu | | 9 | Carl | Etiam.ligula.tortor@auctor.ca | | 10 | Gray | Suspendisse@diamdictum.ca | | 12 | hoge | taro@example.com | +----+---------+---------------------------------------------+
感想
Railsで開発をしている時に、上記挙動を知っていないと取り返しのつかないデータ破損に繋がるため注意して開発したい。