오류 1452를 제대로 이해하려면 먼저 테이블을 하나 생성하고, 외래 키(Foreign Key) 제약 조건을 사용해 다른 테이블과 관계를 맺어 보는 것이 좋습니다. 실제 예제를 통해 오류가 발생하는 상황과 해결 방법을 단계별로 살펴보겠습니다.
예제 테이블 생성
먼저 첫 번째 테이블을 생성합니다.
mysql> CREATE table ForeignTable
-> (
-> id int,
-> name varchar(200),
-> Fk_pk int
-> );
Query OK, 0 rows affected (0.43 sec)
첫 번째 테이블이 성공적으로 생성되었다면, 이번에는 부모 역할을 할 두 번째 테이블을 생성합니다.
mysql> CREATE table primaryTable1
-> (
-> Fk_pk int,
-> DeptName varchar(200),
-> Primary key(Fk_pk)
-> );
Query OK, 0 rows affected (0.48 sec)
외래 키 제약 조건으로 두 테이블 연결
두 개의 테이블이 모두 준비되었으므로, 이제 ALTER 명령과 외래 키 제약 조건을 추가하여 두 테이블을 연결합니다. 기본 문법은 다음과 같습니다.
ALTER TABLE 자식테이블 ADD CONSTRAINT 제약조건이름 FOREIGN KEY (외래키_컬럼) REFERENCES 부모테이블 (기본키_컬럼);
실제로 위 문법을 적용해 두 테이블을 연결하는 쿼리는 다음과 같습니다.
mysql> alter table ForeignTable add constraint constFKPK foreign key(Fk_pk) references primaryTable1(Fk_pk);
Query OK, 0 rows affected (1.57 sec)
Records: 0 Duplicates: 0 Warnings: 0
이제 두 테이블은 외래 키로 서로 연결되었습니다. 'ForeignTable'에 레코드를 바로 삽입해 보겠습니다.
mysql> INSERT into ForeignTable values(1,'John',1);
그러면 아래와 같은 오류 메시지가 출력됩니다.
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`business`.`foreigntable`, CONSTRAINT `constFKPK` FOREIGN KEY (`Fk_pk`)
REFERENCES `primarytable1` (`fk_pk`))
오류 발생 원인
위 출력에서 볼 수 있듯이 'Cannot add or update a child row: a foreign key constraint fails'(하위 행을 추가하거나 업데이트할 수 없음: 외래 키 제약 조건이 실패함)라는 오류가 발생했습니다. 이 오류는 부모 테이블(primaryTable1)에 존재하지 않는 값을 자식 테이블(ForeignTable)의 외래 키 컬럼에 삽입하려고 할 때 발생합니다. 즉, Fk_pk 값 1이 아직 부모 테이블에 등록되지 않았기 때문에 참조 무결성 검사에 실패한 것입니다.
오류 1452가 발생하는 대표적인 원인은 다음과 같습니다.
- 자식 테이블에 삽입하려는 외래 키 값이 부모 테이블에 존재하지 않는 경우
- 두 테이블의 연결 컬럼 간 데이터 타입이 일치하지 않는 경우
- 부모 테이블의 데이터가 삭제되거나 변경되면서 기존 참조 값이 더 이상 유효하지 않게 된 경우
오류 해결 방법
이 오류를 해결하는 가장 확실한 방법은 먼저 부모 테이블인 primaryTable1에 레코드를 삽입하는 것입니다.
mysql> INSERT into primaryTable1 values(1,'ComputerScience');
Query OK, 1 row affected (0.14 sec)
primaryTable1에 레코드를 삽입한 후에는 ForeignTable에도 오류 없이 원하는 레코드를 삽입할 수 있습니다.
mysql> INSERT into ForeignTable values(1,'John',1);
Query OK, 1 row affected (0.13 sec)
결과 확인
SELECT 명령으로 ForeignTable의 레코드를 조회해 보겠습니다.
mysql> SELECT * from ForeignTable;
+------+------+-------+
| id | name | Fk_pk |
+------+------+-------+
| 1 | John | 1 |
+------+------+-------+
1 row in set (0.00 sec)
마찬가지로 primarytable1의 레코드도 SELECT 명령으로 확인할 수 있습니다.
mysql> SELECT * from primarytable1;
+-------+-----------------+
| Fk_pk | DeptName |
+-------+-----------------+
| 1 | ComputerScience |
+-------+-----------------+
1 row in set (0.00 sec)
추가 팁: 대량 데이터 작업 시 임시 우회 방법
대량의 데이터를 마이그레이션하는 동안 일시적으로 외래 키 검사를 비활성화해야 하는 경우에는 다음 명령을 사용할 수 있습니다.
SET FOREIGN_KEY_CHECKS = 0;
-- 데이터 삽입 또는 수정 작업 수행
SET FOREIGN_KEY_CHECKS = 1;
다만 이 방법은 참조 무결성 검증을 건너뛰는 것이므로, 작업이 끝난 후 반드시 데이터 정합성을 확인해야 합니다.
정리
오류 1452(Cannot add or update a child row: a foreign key constraint fails)는 외래 키로 연결된 자식 테이블(ForeignTable)에 데이터를 부모 테이블보다 먼저 삽입하려고 할 때 발생합니다. 부모 테이블에 해당 키 값이 아직 존재하지 않기 때문입니다.
참고: 위 오류를 피하려면 먼저 두 번째 테이블, 즉 primarytable1에 레코드를 추가한 후 자식 테이블에 데이터를 삽입해야 합니다.