Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL 부모 테이블에서 행을 삭제하면 어떻게 될까? 외래 키 제약 조건 오류 완벽 이해

MySQL에서 부모 테이블(parent table)의 행을 삭제하려고 할 때, 해당 행의 데이터가 자식 테이블(child table)에서 참조되고 있다면 외래 키(Foreign Key) 제약 조건 위반으로 인해 삭제가 실패하고 오류가 발생합니다. 이는 잘못된 데이터 참조를 막아 데이터 무결성을 지키기 위한 중요한 안전장치입니다.

예제로 이해하는 부모 테이블과 자식 테이블

이해를 돕기 위해 'customer'(고객)와 'orders'(주문)라는 두 개의 테이블을 예로 들어 보겠습니다. 여기서 'customer'는 부모 테이블, 'orders'는 자식 테이블입니다. 자식 테이블 'orders'에서 참조하고 있는 고객 정보는 부모 테이블 'customer'에서 임의로 삭제할 수 없습니다.

먼저 두 테이블에 저장된 데이터를 확인해 보겠습니다.

mysql> Select * from Customer;
+----+---------+
| id | name    |
+----+---------+
| 1  | Gaurav  |
| 2  | Raman   |
| 3  | Harshit |
| 4  | Aarav   |
+----+---------+
4 rows in set (0.00 sec)

mysql> Select * from orders;
+----------+----------+------+
| order_id | product  | id   |
+----------+----------+------+
| 100      | Notebook | 1    |
| 110      | Pen      | 1    |
| 120      | Book     | 2    |
| 130      | Charts   | 2    |
+----------+----------+------+
4 rows in set (0.00 sec)

위 데이터를 보면 id = 1(Gaurav)과 id = 2(Raman)인 고객은 자식 테이블 'orders'에서 주문 데이터로 참조되고 있습니다. 반면 id = 3, id = 4인 고객은 참조되지 않으므로 자유롭게 삭제할 수 있습니다.

삭제 시도 시 발생하는 오류

이제 부모 테이블 'customer'에서 id = 1 또는 id = 2인 행을 삭제해 보겠습니다. 두 행 모두 자식 테이블에서 사용 중이므로, 외래 키 제약 조건 위반으로 다음과 같은 오류가 발생합니다.

mysql> Delete from customer where id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`query`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`id`) REFERENCES `customer` (`id`))

mysql> Delete from customer where id = 2;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`query`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`id`) REFERENCES `customer` (`id`))

오류 메시지 분석

ERROR 1451 (23000)은 "부모 행을 삭제하거나 수정할 수 없다(Cannot delete or update a parent row)"는 의미입니다. 오류 메시지에는 제약 조건이 걸린 자식 테이블(`query`.`orders`)과 제약 조건 이름(`orders_ibfk_1`), 그리고 참조 관계(`FOREIGN KEY (id) REFERENCES customer(id)`)까지 상세히 표시되므로, 어떤 테이블이 참조하고 있는지 바로 파악할 수 있습니다.

오류 해결 방법

이러한 외래 키 제약 오류를 해결하는 대표적인 방법은 다음과 같습니다.

  • 자식 테이블의 데이터를 먼저 삭제: 부모 행을 삭제하기 전에 해당 행을 참조하는 'orders' 테이블의 주문 데이터를 먼저 삭제한 후 부모 행을 삭제합니다.
  • ON DELETE CASCADE 옵션 사용: 외래 키를 정의할 때 ON DELETE CASCADE를 설정하면, 부모 행이 삭제될 때 이를 참조하는 자식 행들이 자동으로 함께 삭제됩니다.
  • ON DELETE SET NULL 옵션 사용: 부모 행이 삭제될 때 자식 테이블의 외래 키 값이 자동으로 NULL로 변경되어 참조 관계만 끊어집니다.

정리하면, MySQL은 외래 키 제약 조건을 통해 부모 테이블의 행이 자식 테이블에서 참조되는 동안 삭제되는 것을 기본적으로 차단합니다. 따라서 부모 데이터를 삭제하려면 자식 테이블의 참조 관계를 먼저 처리하거나, 테이블 설계 단계에서 적절한 ON DELETE 옵션을 지정해 두는 것이 좋습니다.