MySQL 12 min read

MySQLのERROR 1452・1451 ― 外部キー制約で追加・削除できないときの直し方

※この記事にはアフィリエイト広告(プロモーション)が含まれます。

外部キーで親子関係を付けた表では、親に無い値を子に入れようとすると ERROR 1452、子から参照されている親を消そうとすると ERROR 1451 になります。

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`fkdb`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`fkdb`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))

この記事のログは MySQL 8.4.11(Ubuntu 26.04 の標準パッケージ)で採りました。表は次のとおりです。

CREATE TABLE parent (id int PRIMARY KEY, name varchar(20));
CREATE TABLE child  (id int PRIMARY KEY, parent_id int,
                     FOREIGN KEY (parent_id) REFERENCES parent(id));

まず見る(結論)

括弧の中に、子の表・制約名・子の列・親の表と列が全部出ています。

エラー 操作 対処
1452 子への INSERT / UPDATE 先に親の行を入れる。親が決まらないなら NULL にする
1451 親の DELETE / 主キーの UPDATE 先に子の行を消すか付け替える。ON DELETE CASCADE / SET NULL
1701 親の TRUNCATE DELETE を使う
3730 親の DROP TABLE 先に子の外部キーを外すか子を消す
1452(表名が #sql-...) 既存の表に外部キーを足す ALTER TABLE 孤児行を直してから足す
3780 外部キーを作る 子と親の列の型を合わせる
6125 外部キーを作る 親の列に主キーか一意キーを付ける

NULL は親が無くても入る

parent_id に NULL を入れる INSERT は通りました。親が決まっていない行を許すかどうかは、列の NOT NULL で決めます。

親の側で出るエラー

表ごと消す操作は、1451 とは別の番号になります。

TRUNCATE TABLE parent;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`fkdb`.`child`, CONSTRAINT `child_ibfk_1`)

DROP TABLE parent;
ERROR 3730 (HY000): Cannot drop table 'parent' referenced by a foreign key constraint 'child_ibfk_1' on table 'child'.

制約の一覧を出す

制約名を付けずに作ると、子の表名_ibfk_連番 になります。どの表のどの列がどこを参照しているかは information_schema で引けます。

SELECT table_name, column_name, constraint_name, referenced_table_name, referenced_column_name
  FROM information_schema.key_column_usage
 WHERE table_schema = 'fkdb' AND referenced_table_name IS NOT NULL;
+------------+-------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-----------------+-----------------------+------------------------+
| child      | parent_id   | child_ibfk_1    | parent                | id                     |
+------------+-------------+-----------------+-----------------------+------------------------+

ON DELETE / ON UPDATE の設定は information_schema.referential_constraints の DELETE_RULE / UPDATE_RULE で見ます。何も指定しないと NO ACTION です。

ON DELETE CASCADE と SET NULL

親を消したときの子の扱いを外部キーに書けます。ON DELETE CASCADE の子は行ごと消え、ON DELETE SET NULL の子は parent_id が NULL になりました。

FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE SET NULL

子の行が親無しでは意味を持たないなら CASCADE、親が消えても行を残したいなら SET NULL にします。

FOREIGN_KEY_CHECKS=0 で入った孤児行

SET foreign_key_checks = 0 にすると、検査されずに入ります。1 に戻しても、入った行は検査されません。

SET foreign_key_checks = 0;
INSERT INTO child VALUES (13, 99);   -- 親に 99 は無い
SET foreign_key_checks = 1;

既存の表に外部キーを足す ALTER TABLE も、foreign_key_checks = 0 の間は孤児行があっても通りました。親の無い子は外部結合で探します。

SELECT c.*
  FROM child c LEFT JOIN parent p ON p.id = c.parent_id
 WHERE c.parent_id IS NOT NULL AND p.id IS NULL;
+----+-----------+
| id | parent_id |
+----+-----------+
| 13 |        99 |
+----+-----------+

外部キーを足すときの 1452

孤児行がある表に、検査を有効にしたまま外部キーを足すと 1452 になります。表名が作業用の一時名になるので、元の表名はメッセージに出ません。

ALTER TABLE child2 ADD CONSTRAINT fk_c2 FOREIGN KEY (parent_id) REFERENCES parent(id);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`fkdb`.`#sql-69d_1a`, CONSTRAINT `fk_c2` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))

制約名(fk_c2)から、どの ALTER TABLE かを特定します。

外部キーを作れない(3780 / 6125)

子と親で列の型が違うと作れません。int の親に bigint の子を付けた例です。

ERROR 3780 (HY000): Referencing column 'parent_id' and referenced column 'id' in foreign key constraint 'child3_ibfk_1' are incompatible.

親の列が主キーでも一意キーでもないと 6125 になります。

ERROR 6125 (HY000): Failed to add the foreign key constraint. Missing unique key for constraint 'child4_ibfk_1' in the referenced table 'parent'

8.4 では restrict_fk_on_non_standard_key が既定で ON です。親の列に一意でない普通の索引を付けても、6125 のままでした。

直前のエラーの詳細

SHOW ENGINE INNODB STATUS\G の LATEST FOREIGN KEY ERROR に、最後に失敗した文と親の索引で一番近かった行が出ます。

LATEST FOREIGN KEY ERROR
------------------------
2026-10-21 10:20:33 137221097105088 Transaction:
...
insert into child values (14, 98)
Foreign key constraint fails for table `fkdb`.`child`:
,
  CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
Trying to add in child table, in index parent_id tuple:
...
But in parent table `fkdb`.`parent`, in index PRIMARY,
the closest match we can find is record:

アプリのログに SQL が残っていないとき、失敗した文を後から確かめるのに使えます。

MySQL をもっと深く知るための本

MySQL徹底入門 第5版 MySQL 8.4 LTS対応

翔泳社・2025年6月・MySQL 8.4 LTS 対応

MySQL 8.4 に対応した入門書。日本MySQLユーザ会のメンバーが執筆している。

Amazonで見る

MySQL運用・管理[実践]入門 〜安全かつ高速にデータを扱う内部構造・動作原理を学ぶ

技術評論社・2024年5月

内部構造と動作原理から、運用・管理の考え方を学ぶ。

Amazonで見る

Amazonのアソシエイトとして、FIRE SE は適格販売により収入を得ています。