MySQL을 사용하면서(사실 다른 DBMS에도 공통적으로 발생할 수 있는 문제이지만) 다음과 같은 Error를 마주하였습니다. 나중에 확인하기 위해 작성하였습니다.
INSERT INTO countrylanguage (countrycode, language, isOfficial, percentage) VALUES ('AAA', '외계어', 'F', 10);
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`world`.`countrylanguage`, CONSTRAINT `countryLanguage_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`))
모든 에러가 그렇듯, 영어를 잘 읽으면 됩니다. 바로 외래키 제약 조건에 걸리고 있습니다.
현재 countrylanguage
테이블에 있는 CountryCode
라고 하는 것이 country
의 primary key Code
를 참조하고 있는 외래키인데, 이 foreign key 제약조건에 걸려서 발생하고 있습니다.
원인으로는 country
테이블에 없는 것을 넣고 있는 것이 문제입니다. country
의 Code
에서는 AAA
라는 키가 없는데, 이를 countrylanguage
에서 insert하고 있는 것이 문제입니다.
가장 직관적인 방법은 직접 country
에 AAA
관련 데이터를 추가해주는 방법입니다. 하지만 현 상황에서 dummy data를 추가하는 것은 바람직하지 않아서 이 방법은 제외하였습니다.
외래키 제약조건을 일시적으로 해제하는 방법이 있습니다. 바로 FOREIGN_KEY_CHECKS
를 관리하는 것입니다. 다만 이 방법은 데이터 무결성과 거리가 먼 행위라서 사용할 때 조심해서 사용해야 됩니다.
SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO countrylanguage (countrycode, language, isOfficial, percentage)
VALUES ('AAA', '외계어', 'F', 10);
SET FOREIGN_KEY_CHECKS = 1;
실제로 FOREIGN_KEY_CHECKS
를 다시 1로 바꿔주지 않을 경우 아래와 같은 쿼리로 외래키로 연결된 값을 함부로 삭제가 가능하기 때문에 조심해야됩니다.
DELETE FROM COUNTRY WHERE CODE = 'USA';
2와 유사합니다. 차이점이 있다면 2는 모든 외래키 제약조건을 무시하는 것이고, 이 과정은 해당 테이블 해당 컬럼에 해당하는 외래키 제약조건을 무시하는 행위입니다. 범위는 좀 더 좁지만 역시 무결성을 침해하기 때문에 주의해서 사용해야 됩니다.
ALTER TABLE countrylanguage DROP FOREIGN KEY countryLanguage_ibfk_1;
INSERT INTO countrylanguage (countrycode, language, isOfficial, percentage)
VALUES ('AAA', '외계어', 'F', 10);
ALTER TABLE countrylanguage ADD CONSTRAINT countryLanguage_ibfk_1 FOREIGN KEY (countrycode) REFERENCES country(code);
일반적으로 있는 값으로 넣은 것이 가장 안전한 방법입니다. country
의 Code
에 있는 KOR
을 사용해서 insert
를 실행합니다.
INSERT INTO countrylanguage (countrycode, language, isOfficial, percentage) VALUES('KOR', '외계어', 'F', 10);