mysqlでデータが存在するときinsertしないDML

今回はmysqlでinsertするデータが存在するとき、insert文を実行しないDMLを紹介します。

よくデータベースの作成時にもし存在しなかったら作成するSQL文をみたことがあると思います。
「 IF NOT EXISTS 」です。
CREATE TABLE IF NOT EXISTS `Kin` (
  `category` int(2) NOT NULL,
  `point` int(2) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    

今回はもし存在しなかったらの「 INSERT 」文です。

① INSERT IGNORE
② INSERT ... SELECT


通常のINSERT文
INSERT INTO `Category` VALUES ( 1, 'TEST');

INSERT IGNORE

INSERT IGNORE INTO `Category` VALUES ( 1, 'TEST');
とても簡単ですね。
通常のINSERT文の前に「IGNORE」を追加すればすみます。
しかし、この場合はもしINSERT文がエラーでも正常終了するという
try and catch みたいなものです。

INSERT ... SELECT

INSERT INTO `Category`
SELECT * FROM (SELECT 1, 'TEST') AS tmp
WHERE NOT EXISTS (
    SELECT content FROM Category WHERE content = 'TEST'
) LIMIT 1;

複雑ですが、こちらはIGNOREとは異なり存在しているデータを検索し
該当するテーブルが存在しない場合のみデータをINSERTします。

2種類の違いについて

IGNOREはエラーの場合のみ挿入しない。つまりエラーでなかったら挿入されることになります。例としては、同じプライマリキーが挿入されたり、ユニークカラムにも関わらずデータが挿入されたり基本的な構文エラーになります。
一方でINSERT..SELECTはそのままのSELECT文になるため、自由に挿入の条件を決めることが出来ます。


参考ページ
insert-ignore-vs-insert-on-duplicate-key-update