エラーコード辞典
🚨 mysql-1062 MySQL Error #1062: Duplicate entry
UNIQUE 制約のあるカラムに重複した値を INSERT しようとした
原因
PRIMARY KEY や UNIQUE 制約のあるカラム(典型的には id・email)に既に存在する値を挿入しようとすると発生します。 多重送信 (= 二重 submit) や、 並行リクエストで同じユーザー登録が走った時に出やすいエラーです。
なぜ起きるか (内部仕組み)
UNIQUE 制約は MySQL が物理的に索引 (= index) でユニーク性を保証する仕組みです。 INSERT 実行時に既存索引と衝突すると、 トランザクション内であってもその時点で 1062 で fail し ROLLBACK されます。 「先に SELECT で存在チェックして、 無ければ INSERT」 というロジックは、 並行リクエスト下では SELECT と INSERT の間に他の transaction が INSERT する race condition が残るため、 unique 制約に最終的な保証を委ねるのが安全です。
よくあるシナリオ
1. ユーザー登録フォームを連打されて email が二重 INSERT される。 2. AUTO_INCREMENT で id を生成しているはずなのに、 アプリ側で id を明示指定して既存値とぶつかる。 3. import スクリプトで CSV を再実行して、 同じ key を 2 度 INSERT する。 4. レプリケーション (= master/slave) で auto_increment_offset がずれて id 重複が発生する。
対処方法
事前に `SELECT` で存在チェックする、または `INSERT ... ON DUPLICATE KEY UPDATE` 構文を使います。AUTO_INCREMENT で id を生成しているなら id 指定を外します。 PHP 側では `try { $pdo->execute(...); } catch (PDOException $e) { if ($e->getCode() === "23000") { /* 重複として扱う */ } }` のようにエラーコードを判定して、 ユーザーに「既に登録済です」 とフィードバックします。
再発防止 / 予防策
冪等性 (= 同じ操作を何回繰り返しても結果が変わらない) を意識した API 設計 (= idempotency key) + クライアント側の二重 submit ガード + サーバー側の unique 制約、 という多層防御で対策します。