[데이터베이스] MySQL Cascade Delete 깊이 제한

Narcoker·2025년 9월 2일
0

데이터베이스

목록 보기
19/21

MySQL Cascade Delete 깊이 제한

외래 키(Foreign Key)를 설정할 때 ON DELETE CASCADE 옵션을 주면,
부모 레코드가 삭제될 때 이를 참조하는 자식 레코드도 자동으로 삭제된다.

이론적으로는 무한 전파가 가능하지만
MySQL(InnoDB 엔진)에서는 이 전파 깊이를
무한 루프나 과도한 재귀 처리를 막기 위해
최대 15단계 까지만 가능하게 하드코딩해놨다고 한다. (확장 불가)

만약 이 제한을 풀고 싶다면 애플리케이션 단에서 로직을 작성하던가
WITH CTE (재귀) 를 사용해야한다.

실습

MySQL 환경에서 실제로 그런지 확인해봤다.

아래는 실행한 SQL 문이다.
t1 ~ t16 Table을 생성하고 각 테이블별 컬럼은 id와 parent_id 가 있다.

t1를 루트 테이블로 사용하고 t16 까지
단방향으로 FKON DELETE CASCADE 를 설정했다.

데이터를 삽입 후 t1의 있는 레코드를 삭제했더니 다음과 같은 에러가 나왔다.

Error Code: 3008. Foreign key cascade delete/update exceeds max depth of 15.

-- 기존 테이블 있으면 다 삭제
DROP TABLE IF EXISTS t16, t15, t14, t13, t12, t11, t10, t9, t8, t7, t6, t5, t4, t3, t2, t1;

-- 1단계 테이블
CREATE TABLE t1 (
    id INT PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB;

-- 2~16단계 테이블 반복 생성
CREATE TABLE t2 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t1(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t3 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t2(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t4 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t3(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t5 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t4(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t6 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t5(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t7 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t6(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t8 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t7(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t9 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t8(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t10 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t9(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t11 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t10(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t12 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t11(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t13 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t12(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t14 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t13(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t15 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t14(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE t16 (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES t15(id) ON DELETE CASCADE
) ENGINE=InnoDB;

INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1, 1);
INSERT INTO t3 VALUES (1, 1);
INSERT INTO t4 VALUES (1, 1);
INSERT INTO t5 VALUES (1, 1);
INSERT INTO t6 VALUES (1, 1);
INSERT INTO t7 VALUES (1, 1);
INSERT INTO t8 VALUES (1, 1);
INSERT INTO t9 VALUES (1, 1);
INSERT INTO t10 VALUES (1, 1);
INSERT INTO t11 VALUES (1, 1);
INSERT INTO t12 VALUES (1, 1);
INSERT INTO t13 VALUES (1, 1);
INSERT INTO t14 VALUES (1, 1);
INSERT INTO t15 VALUES (1, 1);
INSERT INTO t16 VALUES (1, 1);

DELETE FROM t1 WHERE id = 1;

간단하게 알아본 DBMS 별 Cascade 제한

SQL Server (MSSQL)

최대 32단계까지 허용

Oracle Database

깊이 제한 없음

사이클 참조(A→B→C→A 같은 구조)만 금지

이론적으로 수천 단계도 가능하지만, 성능 문제가 있을 수 있어 권장하지 않음

PostgreSQL

깊이 제한 없음

Oracle과 동일하게 사이클만 금지

ON DELETE CASCADE가 걸린 FK는 끝까지 따라가며 삭제됨

하지만 10단계 이상 체인은 성능 부담이 크므로 보통 애플리케이션 로직으로 처리하는 경우가 많음

profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글