DB

[MySQL] 외래키 참조 무결

Raconer 2024. 12. 16. 00:28
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

주의사항

  1. 외래 키 설정 시 자식 테이블이 먼저 생성되어야 함
    • 부모 테이블을 참조하는 외래 키를 정의하려면, 자식 테이블 생성 전에 부모 테이블이 존재해야 합니다.
  2. SET NULL 조건
    • 외래 키 컬럼이 NULL을 허용하지 않으면 에러가 발생하므로, 반드시 NULLABLE 설정 필요.
  3. NO ACTION vs RESTRICT
    • 두 옵션은 거의 동일하지만, MySQL 내부 동작에서 약간의 차이가 있습니다. 일반적으로 RESTRICT를 더 명시적으로 사용합니다.

 

728x90