728x90
MySQL에서 외래 키(Foreign Key, FK)를 설정할 때 ON DELETE와 ON UPDATE 옵션은 참조 무결성(Referential Integrity)을 유지하기 위한 동작 방식을 정의합니다.
이 옵션들은 부모 테이블의 데이터가 삭제되거나 업데이트될 때, 자식 테이블에서 어떻게 처리할지를 설정합니다.
ON DELETE 및 ON UPDATE 옵션 종류
1. CASCADE
- 부모 테이블의 행이 삭제되거나 업데이트되면, 해당 외래 키를 참조하는 자식 테이블의 행도 자동으로 삭제되거나 업데이트됩니다.
- 주로 부모-자식 관계에서 데이터가 함께 삭제되거나 변경되어야 할 때 사용합니다.
- 예: 게시글 삭제 시 댓글도 삭제됨.
예제
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE CASCADE
);
2. SET NULL
- 부모 테이블의 행이 삭제되거나 업데이트되면, 자식 테이블의 해당 외래 키 값이 NULL로 설정됩니다.
- 자식 테이블의 외래 키 컬럼이 NULL을 허용해야 합니다.
- 예: 사용자 정보 삭제 시 주문 테이블에서 user_id를 NULL로 설정.
예제
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE SET NULL ON UPDATE SET NULL
);
3. NO ACTION
- 부모 테이블의 행이 삭제되거나 업데이트되더라도, 자식 테이블에 아무런 영향을 주지 않습니다.
- 단, 무결성을 유지하기 위해, 자식 테이블에서 해당 외래 키 값을 참조하고 있다면 부모 테이블의 변경 작업이 거부됩니다.
- 실질적으로 RESTRICT와 동일하게 동작합니다.
- 예: 삭제하려는 데이터를 참조 중인 경우 에러 발생.
예제
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
4. RESTRICT
- 부모 테이블의 행이 삭제되거나 업데이트될 때, 자식 테이블에서 해당 외래 키 값을 참조 중이라면 거부됩니다.
- NO ACTION과 유사하지만, MySQL에서 외래 키를 바로 확인하여 삭제나 업데이트를 거부합니다.
예제
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
5. SET DEFAULT
- 부모 테이블의 행이 삭제되거나 업데이트되면, 자식 테이블의 외래 키 값이 기본값(Default)으로 설정됩니다.
- MySQL은 이 옵션을 지원하지 않으며, 대신 다른 DBMS(PostgreSQL, SQL Server 등)에서 사용 가능합니다.
예제
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE RESTRICT ON UPDATE RESTRICT
);
옵션별 동작 요약
옵션ON DELETE 동작ON UPDATE 동작
CASCADE | 자식 테이블의 행도 함께 삭제 | 자식 테이블의 외래 키 값도 함께 업데이트 |
SET NULL | 자식 테이블의 외래 키 값이 NULL로 변경 | 자식 테이블의 외래 키 값이 NULL로 변경 |
NO ACTION | 참조 중이면 삭제/업데이트 거부 | 참조 중이면 삭제/업데이트 거부 |
RESTRICT | 참조 중이면 삭제/업데이트 거부 | 참조 중이면 삭제/업데이트 거부 |
SET DEFAULT | 자식 테이블의 외래 키가 기본값으로 설정 | 자식 테이블의 외래 키가 기본값으로 설정 |
사용 예제
1. 부모-자식 관계에서 함께 삭제 (CASCADE)
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);
-- 부모 데이터 삽입
INSERT INTO parent VALUES (1);
INSERT INTO child VALUES (1, 1);
-- 부모 데이터 삭제 → 자식 데이터도 삭제
DELETE FROM parent WHERE id = 1;
-- child 테이블 비어 있음
SELECT * FROM child; -- 결과: 0 rows
2. 참조된 데이터 삭제 거부 (RESTRICT)
CREATE TABLE parent (
id INT PRIMARY KEY
);
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE RESTRICT
);
-- 부모 데이터 삽입
INSERT INTO parent VALUES (1);
INSERT INTO child VALUES (1, 1);
-- 부모 데이터 삭제 시 에러 발생 (참조 중)
DELETE FROM parent WHERE id = 1; -- ERROR: Cannot delete or update a parent row
주의사항
- 외래 키 설정 시 자식 테이블이 먼저 생성되어야 함
- 부모 테이블을 참조하는 외래 키를 정의하려면, 자식 테이블 생성 전에 부모 테이블이 존재해야 합니다.
- SET NULL 조건
- 외래 키 컬럼이 NULL을 허용하지 않으면 에러가 발생하므로, 반드시 NULLABLE 설정 필요.
- NO ACTION vs RESTRICT
- 두 옵션은 거의 동일하지만, MySQL 내부 동작에서 약간의 차이가 있습니다. 일반적으로 RESTRICT를 더 명시적으로 사용합니다.
728x90
'DB' 카테고리의 다른 글
[MySQL] WITH RECURSIVE( 재귀 ) (0) | 2024.12.16 |
---|---|
[ MySQL] WITH 절 (0) | 2024.12.16 |
[MySQL] Query 성능 향상 _ 1(JOIN 및 SUM, COUNT) (0) | 2024.12.16 |
[MySQL] 복합 인덱스(Multiple-Column Indexes) (0) | 2024.12.12 |
[MySQL] Index 공식 문서 읽어 보기 (0) | 2024.12.12 |