ON DELETE CASCADE (feat. foreign key 로 연결된 row 한 번에 지우는 방법) (TIL 78일차)

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails


DELETE

학생

id이름학번
1eensungkim2020001
2kimcoding2020003

DELETE 는 테이블 내의 레코드를 삭제할 때 사용하는 명령어입니다. 학생에 관한 정보를 모아둔 위와 같은 테이블이 있다고 할 때, DELETE 를 활용하면 조건에 따라 개별 학생의 정보가 담긴 row 를 하나씩 지우거나, 혹은 테이블 내의 모든 row 를 지우는 것이 가능합니다.

하지만 여러 개의 테이블이 foreign key 로 묶여있을 경우에는 상황이 조금 다릅니다. 서로가 연결되어 있기 때문에 어느 하나를 지워서는 정보가 꼬이는 상황이 발생할 수 있죠. MySQL 에서는 만약 어떤 테이블의 row 의 정보가 다른 테이블과 foreign key 로 묶여있을 때 DELETE 명령어를 사용해 row 를 삭제하려고 하면, ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 와 같은 에러 메시지를 보여주며 DELELTE 처리를 거부합니다.

에러 메시지를 살펴보면 parent row 라는 표현을 확인할 수 있습니다. foreign key 로 묶일 때 부모와 자식의 관계가 성립하기 때문인데요. primary key 값을 foreign key 로 전달하는 쪽이 '부모', foreign key 를 받아오는 쪽이 '자식' 이라고 할 수 있습니다.

부모 쪽의 row 를 먼저 지울 수는 없지만 자식 쪽의 row 를 지우는 것은 가능합니다. 연결된 자식 데이터를 전부 지우고 나면 부모 쪽의 데이터를 지우는 것이 가능합니다.


ON DELETE CASCADE

foreign key 로 연결된 데이터들이 일관성을 유지할 수 있도록 하기 위해서, foreign key constraints 라는 것이 있습니다. 공식 문서는 CASCADE 를 foreign key constraints 에서 옵션으로 사용할 수 있는 Referential Actions 이라고 설명합니다.

CASCADE 는 부모 테이블의 row 에 DELETE 또는 UPDATE 명령어를 적용할 때, 자동적으로 자식 테이블의 매치되는 row 에도 똑같이 DELETE 또는 UPDATE 를 반영하는 것을 의미합니다. 이를 사용하기 위해서는 foreign key constraints 옵션에 ON DELETE CASCADE 를 설정해주어야 합니다. (ON UPDATE CASCADE 를 설정하면 UPDATE 를 할 때 CASCADE 옵션이 적용되겠죠.)

ON DELETE CASCADE 옵션을 적용하면 부모 테이블에서 row 를 삭제할 경우 연결된 자식 테이블의 row 가 함께 삭제됩니다. 연결된 데이터를 한 번에 지울 수 있어 데이터의 관리가 편리해지고 일관성을 유지할 수 있습니다.

ON DELETE CASCADE 는 테이블의 생성 시, 다시 말해 CREATE TABLE 명령어를 사용해 테이블을 생성할 때 적용하게 됩니다. 만약 이미 테이블이 생성되었다면, ALTER TABLE 명령어를 활용해 기존의 foreign key 부분을 지웠다가 다시 생성하는 방식으로 사용할 수 있습니다.

기존의 foreign key 를 제거하고 다시 추가하는 방법은 다음과 같습니다.

// _로 연결된 부분에 사용할 값을 넣으시면 됩니다.
// 기존의 foreign key 지우는 방법
ALTER TABLE table_name DROP FOREIGN KEY foreign_key_symbol

// 실제 사용 예제
ALTER TABLE order_items DROP FOREIGN KEY order_items_ibfk_1;

// ON DELETE CASCADE 포함한 foreign key 재생성
// 괄호가 있는 경우 괄호를 꼭 사용해야 합니다.
ALTER TABLE 자식_table_name 
ADD FOREIGN KEY (foreign_key_연결받을_자식_테이블의_column_name) 
REFERENCES 부모_table_name (foreign_key_로_가져올_column_name)
ON DELETE CASCADE;

// 실제 사용 예제
ALTER TABLE order_items 
ADD FOREIGN KEY (item_id) 
REFERENCES orders (id)
ON DELETE CASCADE;

경우에 따라 추가적인 명령어가 활용될 수 있으며 이에 대해 더 자세하게 알고 싶으신 분들은 위에서 언급한 공식 문서의 Adding Foreign Key Constraints 부분을 참고하시면 되겠습니다.


SHOW CREATE TABLE

기존의 테이블이 어떻게 생성되었는지를 확인하기 위해서 SHOW CREATE TABLE 명령어를 사용할 수 있습니다. 공식 문서 에서 확인하실 수 있습니다.

SHOW CREATE TABLE 테이블_이름\G

명령어 뒤에 확인하고자 하는 테이블의 이름을 넣고 \G 를 붙여주면 다음처럼 테이블이 생성될 때 어떤 정보들을 가지고 생성되었는지를 확인할 수 있습니다.


foreign key symbol 은 어떻게 알 수 있나요?

foreign key 를 제거할 때 symbol 을 알고 있어야 제거가 가능한데요. SHOW CREATE TABLE 을 활용해서 쉽게 찾아낼 수 있습니다.

상단 이미지의 foreign key 부분을 보시면 CONSTRAINT 'order_items_ibfk_1' 라는 부분이 FOREIGN KEY 앞에 있는 걸 확인하실 수 있는데요. 이 부분이 foreign key 의 symbol 입니다. foreign key constraint 를 생성할 때 따로 symbol 을 지정해주지 않을 경우 자동으로 생성됩니다.


공식 문서 외 참고자료

https://www.mysqltutorial.org/mysql-on-delete-cascade/

https://daily-life-of-bsh.tistory.com/207

좋은 웹페이지 즐겨찾기