MySQLのエラー『エラー1062: Duplicate Entry』の解決方法

MySQLのエラー『エラー1062: Duplicate Entry』の解決方法

MySQLでデータのINSERTまたはUPDATEを行った際に「エラー1062: Duplicate entry ‘X’ for key ‘Y’」が表示されることがある。これは、PRIMARY KEYやUNIQUE制約を持つカラムに対して、すでに存在する値を挿入しようとした場合に発生する。エラーの発生条件とその対処法を具体的に説明する。

1. エラーの発生条件

PRIMARY KEY、UNIQUE INDEXが設定されているカラムに、重複する値をINSERTまたはUPDATEしようとすると発生する。

CREATE TABLE users (
  id INT PRIMARY KEY,
  email VARCHAR(255) UNIQUE
);

INSERT INTO users (id, email) VALUES (1, 'test@example.com');
-- 正常に挿入される

INSERT INTO users (id, email) VALUES (2, 'test@example.com');
-- エラー1062: Duplicate entry 'test@example.com' for key 'email'

2. 重複する値を確認する

重複している値を探すためには、対象のカラムに同じ値が既に存在していないかを確認する必要がある。

SELECT * FROM users WHERE email = 'test@example.com';

3. 重複を避けるためのINSERT前チェック

INSERT前に該当の値が既に存在するかをチェックする方法。

IF NOT EXISTS (
  SELECT 1 FROM users WHERE email = 'test@example.com'
) THEN
  INSERT INTO users (id, email) VALUES (3, 'test@example.com');
END IF;

4. INSERT IGNOREの使用

重複エラーを無視してスキップしたい場合、INSERT IGNOREを使うことで処理を継続できる。

INSERT IGNORE INTO users (id, email) VALUES (4, 'test@example.com');

5. ON DUPLICATE KEY UPDATEの使用

すでにレコードが存在する場合にUPDATEを行いたい場合、ON DUPLICATE KEY UPDATEを使用する。

INSERT INTO users (id, email) VALUES (5, 'test@example.com')
ON DUPLICATE KEY UPDATE email = VALUES(email);

6. AUTO_INCREMENTの衝突

テーブルのAUTO_INCREMENT値が既存のレコードと衝突している場合も、このエラーが出ることがある。

-- 現在の最大IDを確認
SELECT MAX(id) FROM users;

-- AUTO_INCREMENT値を修正
ALTER TABLE users AUTO_INCREMENT = 100;

7. 重複の原因が複合キーにある場合

複数のカラムに対してUNIQUE INDEXが張られている場合も、エラーは発生する。

CREATE TABLE orders (
  user_id INT,
  product_id INT,
  UNIQUE KEY unique_user_product (user_id, product_id)
);

-- 同じuser_idとproduct_idの組み合わせでINSERTするとエラー

8. 重複しているキーの特定

エラーメッセージには「for key ‘key_name’」と表示されるので、key_nameをもとにINDEX定義を確認する。

SHOW INDEX FROM users;

9. 一意性制約を削除する

場合によってはUNIQUE制約が不要なこともある。その場合は制約を削除することでエラーを回避できる。

ALTER TABLE users DROP INDEX email;

10. データ挿入時の一括処理での注意点

大量のINSERT文を一括実行した場合、1件でも重複があると全体がロールバックされることがある。INSERT IGNOREやON DUPLICATE KEY UPDATEの使用を検討する。

11. 一意性の条件に気づきにくいパターン

UNIQUE制約が付いているがアプリケーション側でバリデーションされておらず、同じ値が複数送られてしまうケースも多い。入力チェックやバリデーションを設計に組み込むことが重要になる。

12. エラーメッセージのサンプル

以下のようなメッセージが表示された場合、そのキーをもとに対処を考える。

ERROR 1062 (23000): Duplicate entry 'test@example.com' for key 'users.email'