903

多くの行を含むステートメントを実行しているINSERTときに、失敗の原因となる重複エントリをスキップしたいと考えています。いくつかの調査の後、私のオプションは次のいずれかを使用するようです。

  • ON DUPLICATE KEY UPDATEこれは、何らかのコストで不要な更新を意味する、または
  • INSERT IGNORE予告なしに滑り込む他の種類の失敗への招待を意味します。

私はこれらの仮定で正しいですか?重複を引き起こす可能性のある行を単純にスキップして、他の行に進む最善の方法は何ですか?

4

12 に答える 12

189

これが何を意味するのかを知りたい場合は、ここにすべてのブローバイブローを示します。

CREATE TABLE `users_partners` (
  `uid` int(11) NOT NULL DEFAULT '0',
  `pid` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`uid`,`pid`),
  KEY `partner_user` (`pid`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

主キーは、このクイック リファレンス テーブルの両方の列に基づいています。主キーには一意の値が必要です。

さぁ、始めよう:

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...1 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1);
...0 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1) ON DUPLICATE KEY UPDATE uid=uid
...0 row(s) affected

上記は、列をそれ自体に等しく設定することで余分な作業を大幅に節約したことに注意してください。実際には更新は必要ありません

REPLACE INTO users_partners (uid,pid) VALUES (1,1)
...2 row(s) affected

そして今、いくつかの複数行のテスト:

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...3 row(s) affected

コンソールで他のメッセージは生成されず、テーブル データにこれら 4 つの値が含まれるようになりました。(1,1) 以外のすべてを削除して、同じ競技場からテストできるようにしました

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4) ON DUPLICATE KEY UPDATE uid=uid
...3 row(s) affected

REPLACE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...5 row(s) affected

それで、あなたはそれを持っています。これはすべて、データがほとんどなく、本番環境ではない新しいテーブルで実行されたため、実行時間は微視的であり、無関係でした。実世界のデータを持っている人なら誰でも、喜んで貢献してくれるでしょう。

于 2011-10-21T18:23:12.367 に答える
22

上記のように、INSERT..IGNORE を使用すると、INSERT ステートメントの実行中に発生したエラーは代わりに警告として扱われます。

明示的に言及されていないことの 1 つは、INSERT..IGNORE により、無効な値が挿入時に最も近い値に調整されることです (一方、IGNORE キーワードが使用されていない場合、無効な値によりクエリが中止されます)。

于 2010-09-16T14:48:18.533 に答える