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 | 이름 | 학번 |
---|---|---|
1 | eensungkim | 2020001 |
2 | kimcoding | 2020003 |
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
Author And Source
이 문제에 관하여(ON DELETE CASCADE (feat. foreign key 로 연결된 row 한 번에 지우는 방법) (TIL 78일차)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eensungkim/ON-DELETE-CASCADE-feat.-row-한-번에-지우는-방법-TIL-78일차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)