- MySQL
MySQL ERROR 1452の直し方|外部キー制約エラー
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails は、子のテーブル(注文など)に、親のテーブル(顧客など)に存在しない値を入れようとしたときのエラーです。 逆に、子から参照されている親を消そうとすると 1451 になります。
| エラー | 起きたこと | 直し方 |
|---|---|---|
| 1452 Cannot add or update a child row | 子に、親に無い値を入れようとした | 先に親を登録する/値の間違いを直す |
| 1451 Cannot delete or update a parent row | 子から使われている親を消そう・変えようとした | 先に子を消す/ON DELETE の動きを決める |
| 3730 Cannot drop table ... referenced by a foreign key | 子から参照されている親のテーブルを DROP | 子の外部キーを先に消す |
| 1701 Cannot truncate a table referenced in a foreign key | 親を TRUNCATE | DELETE を使う、または子を先に |
確認環境:MySQL 8.0.46(InnoDB)(確認日 2026年10月11日)。顧客(customers2)と注文(orders2)の2つのテーブルで再現しました。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「MySQL ERROR 1452の直し方|外部キー制約エラー」
再現と、エラー文の読み方
CREATE TABLE customers2 (id int PRIMARY KEY, name varchar(20));
CREATE TABLE orders2 (
id int PRIMARY KEY,
customer_id int NOT NULL,
CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers2 (id)
);
INSERT INTO customers2 VALUES (1, '佐藤'), (2, '鈴木');
INSERT INTO orders2 VALUES (11, 3); -- 顧客 3 はいない
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`mig`.`orders2`, CONSTRAINT `fk_orders_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers2` (`id`))
| 部分 | 意味 |
|---|---|
`mig`.`orders2` |
子のテーブル(入れようとした側) |
FOREIGN KEY (`customer_id`) |
子の列(入れようとした値の列) |
REFERENCES `customers2` (`id`) |
親のテーブルと列(ここに値が必要) |
「orders2.customer_id に入れた値が、customers2.id に無い」と読みます。エラー文には値そのものは出ないので、入れようとした値(ここでは 3)を確かめ、親に存在するかを調べます。
SELECT * FROM customers2 WHERE id = 3; -- 0 件なら、親が無い
1452 のよくある原因
| 原因 | 例 |
|---|---|
| データを入れる順番が逆 | 移行で、注文を先に入れ、顧客をあとから入れる |
| 値の間違い | 存在しない ID・0・空文字が入ってくる(画面の初期値など) |
| 親を消したあと | 別の処理が先に顧客を消していた |
| 既存の子データに、親の無い行がある | ALTER TABLE ... ADD FOREIGN KEY が 1452 で失敗する |
ALTER TABLE child2 ADD CONSTRAINT fk_child FOREIGN KEY (cid) REFERENCES customers2 (id);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mig`.`#sql-1c4_78`, ...)
外部キーを後から追加するときは、テーブル名が #sql-... という一時的な名前で表示されました。 既存のデータに、親の無い行があるという意味です。
親の無い子データを探す
SELECT o.id, o.customer_id
FROM orders2 o
LEFT JOIN customers2 c ON c.id = o.customer_id
WHERE c.id IS NULL;
id customer_id
11 3
12 99
LEFT JOIN で親がつながらなかった行が、親の無い子データです。親を登録するか、子のデータを直す・消すかを決めます。
1451:親を消そうとしたとき
DELETE FROM customers2 WHERE id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails
(`mig`.`orders2`, CONSTRAINT `fk_orders_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers2` (`id`))
顧客 1 には注文があるため、消せません。親の ID を変える UPDATE も同じエラーになりました。
| 方法 | 内容 |
|---|---|
| 子を先に消す | DELETE FROM orders2 WHERE customer_id = 1; → 親を消す |
外部キーに ON DELETE CASCADE |
親を消すと子も一緒に消える |
外部キーに ON DELETE SET NULL |
親を消すと子の列が NULL になる(列が NULL 可のとき) |
| 消さずに「無効」の印を付ける | 顧客に deleted_at などの列を持たせる |
ON DELETE の動きの違いは、関連記事の「外部キーON DELETE CASCADE|SET NULL・RESTRICT比較」で詳しく比べています。
データ移行の順番
| 入れる(INSERT・取り込み) | 消す(DELETE) |
|---|---|
| 親 → 子(顧客 → 注文 → 注文明細) | 子 → 親(注文明細 → 注文 → 顧客) |
テーブルの数が多く順番を決めにくい場合に、FOREIGN_KEY_CHECKS を 0 にする方法もありますが、次の注意があります。
注意:FOREIGN_KEY_CHECKS=0 で入れた不整合は、後から別の更新を止める
SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO orders2 VALUES (11, 3), (12, 99); -- 親の無い行が入る(エラーにならない)
SET FOREIGN_KEY_CHECKS = 1; -- 戻してもエラーにならない
FOREIGN_KEY_CHECKS を 1 に戻しても、入れてしまった行はチェックされませんでした(MySQL 公式マニュアルでも、戻したときに既存のデータは確かめないとされています)。そして、その行はあとで関係のない更新を止めました。
| その行への更新 | 結果 |
|---|---|
UPDATE orders2 SET customer_id = 99 WHERE id = 12(同じ値) |
エラーにならない(変更なし) |
UPDATE orders2 SET id = 13 WHERE id = 12(外部キーと関係ない列) |
ERROR 1452 |
外部キーの列を変えていないのに 1452 になるので、原因が分かりにくくなります。FOREIGN_KEY_CHECKS = 0 で取り込んだあとは、必ず上の LEFT JOIN で、親の無い行が無いかを確かめます。
外部キーを作るときのエラー
CREATE TABLE bad_fk (id int PRIMARY KEY, cid bigint, FOREIGN KEY (cid) REFERENCES customers2 (id));
ERROR 3780 (HY000): Referencing column 'cid' and referenced column 'id' in foreign key constraint 'bad_fk_ibfk_1' are incompatible.
子の列と親の列の型が違う(bigint と int)と、外部キーを作れませんでした。公式マニュアルでは、整数の型は大きさと符号(UNSIGNED かどうか)、文字列の型は文字コードと照合順序までそろえる必要があるとされています。
もっと詳しく調べる:LATEST FOREIGN KEY ERROR
SHOW ENGINE INNODB STATUS\G
LATEST FOREIGN KEY ERROR
------------------------
... update orders2 set id=13 where id=12
Foreign key constraint fails for table `mig`.`orders2`:
CONSTRAINT `fk_orders_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers2` (`id`)
Trying to add in child table, in index fk_orders_customer tuple:
...
直近の外部キーのエラーで、実行した SQL と、どの制約に引っかかったかが残ります。アプリから実行した SQL が分からないときに使えます。
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | 1452 か 1451 か | 1452 は子に入れる、1451 は親を消す・変える |
| 2 | 子の列と親の表・列 | エラー文の FOREIGN KEY (...) REFERENCES ... (...) |
| 3 | 入れようとした値が親にあるか | SELECT * FROM 親 WHERE id = 値 |
| 4 | 親の無い子データ | LEFT JOIN で 親.id IS NULL |
| 5 | 入れる・消す順番 | 入れるのは親→子、消すのは子→親 |
| 6 | FOREIGN_KEY_CHECKS=0 を使ったか | 戻したあとに LEFT JOIN で確かめる |
よくある質問
Q. 外部キーを外せば解決しますか。 A. エラーは出なくなりますが、親の無い注文のような不整合なデータが入るようになります。外部キーは、データの整合性を DB が守ってくれる仕組みなので、入れる順番や値を直すほうを選びます。
Q. NULL を入れたらどうなりますか。
A. 子の列が NULL を許可していれば、NULL は外部キーのチェックの対象外です(親が無いことを表せます)。NOT NULL の列なら、確認環境では ERROR 1048: Column 'customer_id' cannot be null という、外部キーとは別のエラーになりました。
まとめ
- 1452 は子に親の無い値、1451 は子が使っている親を消す・変える
- エラー文の
FOREIGN KEY (子の列) REFERENCES 親の表 (親の列)を読み、値が親にあるか確かめる - 入れるのは親→子、消すのは子→親
- 親の無い子データは LEFT JOIN で
親.id IS NULL FOREIGN_KEY_CHECKS=0で入れた不整合は、戻しても残り、あとで関係のない更新を 1452 で止める- 外部キーを作るときは、型・符号・文字コードをそろえる(3780)
参考・出典
確認日はいずれも 2026年10月11日です。
- MySQL 8.0 Reference Manual「FOREIGN KEY Constraints」:https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「MySQL ERROR 1452の直し方|外部キー制約エラー」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。