MySQLのエラー『エラー121: Duplicate Key』の解決方法

MySQLでINSERTやALTER TABLE、CREATE TABLEなどを行った際に「ERROR 121 (HY000): Duplicate key on write or update」が表示される場合がある。このエラーは、主にインデックスや外部キーの重複によって引き起こされる。
1. エラーの発生条件
次のような操作でエラー121が発生する。
- INSERTで一意キーに既存値を挿入しようとした場合
- ALTER TABLEで同じ名前のインデックスを作成しようとした場合
- CREATE TABLEで外部キー名が既に使われている場合
ALTER TABLE orders ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id);
ERROR 121 (HY000): Duplicate key on write or update
2. INSERT時の一意キー重複による発生
UNIQUEまたはPRIMARY KEYが設定されているカラムに対して、既に存在する値を挿入しようとした場合に発生する。
INSERT INTO users (id, email) VALUES (1, 'test@example.com');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
※この場合、実際のエラーコードは1062だが、複合操作の中で121に変換されるケースがある。
3. CREATE TABLEで外部キー名が重複しているケース
InnoDBで外部キーを設定する際、同一の外部キー名(CONSTRAINT名)を再利用しようとするとエラー121が発生する。
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id)
);
すでに別のテーブルで「fk_user_id」という名前の外部キーが使われているとエラーになる。
4. ALTER TABLEでのインデックス名の重複
ALTER TABLEで新しいインデックスや外部キーを追加する際に、すでに同名のインデックスが存在する場合にもこのエラーが発生する。
ALTER TABLE orders ADD CONSTRAINT fk_user_id_orders FOREIGN KEY (user_id) REFERENCES users(id);
自動生成名が被らないようにするためにも、明示的な命名が推奨される。
6. 既存のインデックス・外部キーを確認する
既に定義されているキーや制約名を確認するには、INFORMATION_SCHEMAを使用する。
SELECT CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'orders' AND CONSTRAINT_TYPE = 'FOREIGN KEY';
7. SHOW CREATE TABLEで現在の定義を確認
外部キーやインデックスの状況を視覚的に確認するには、SHOW CREATE TABLEが便利。
SHOW CREATE TABLE orders\G
8. 外部キーを一度削除してから再定義
重複している可能性のあるキーを削除してから、新たに正しく定義し直す。
ALTER TABLE orders DROP FOREIGN KEY fk_user_id;
ALTER TABLE orders ADD CONSTRAINT fk_user_id_orders FOREIGN KEY (user_id) REFERENCES users(id);
9. テーブル削除時にも注意が必要
外部キーが設定されたままのテーブルを再作成しようとすると、エラー121になることがある。その場合、先に外部キーを解除してからDROP TABLEを実行する。
10. mysqldump後のリストアで発生するケース
mysqldumpで複数テーブルをダンプし、順番を入れ替えてインポートすると外部キー重複で121エラーになることがある。–skip-add-drop-tableや–no-create-infoオプションを適宜使用する。
11. 一意キーでのサンプルテーブルとINSERT
CREATE TABLE products (
id INT PRIMARY KEY,
code VARCHAR(20) UNIQUE
);
INSERT INTO products (id, code) VALUES (1, 'A001');
-- 以下はエラーになる
INSERT INTO products (id, code) VALUES (2, 'A001');
12. 外部キー名が重複しないようにする命名規則
テーブル名+カラム名をベースに、プロジェクトごとに一貫性のある命名ルールを決めておくと、エラー121の予防になる。
-- Good
CONSTRAINT fk_orders_user_id
-- Bad(他テーブルと被りやすい)
CONSTRAINT fk_user_id
-
前の記事
MariaDB タンジェントの値を計算する 2025.05.02
-
次の記事
ReactとD3.jsで作るインタラクティブなデータビジュアライゼーション 2025.05.02
コメントを書く