406. 참조 무결성 (Referential Integrity)

⚠️ 이 문서는 데이터베이스의 두 테이블이 외래 키(Foreign Key)로 연결되어 있을 때, "없는 부서에 직원을 배치하거나, 직원이 남아있는 부서를 함부로 지우는 행위"를 원천 차단하여 테이블 간의 릴레이션(관계)을 안전하게 지켜주는 '참조 무결성' 규칙을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 외래 키(FK)에 들어가는 값은 반드시 상대방 테이블의 기본 키(PK)에 실제로 존재하는 값이어야 하거나, 아예 Null이어야 한다는 규칙이다. (없는 것을 가리킬 수 없음)
  2. 제한 행위: 이 규칙 때문에, 부모 테이블의 데이터를 함부로 삭제(Delete)하거나 수정(Update)할 수 없게 되며, 자식 테이블에 엉뚱한 데이터를 삽입(Insert)할 수도 없게 된다.
  3. 해결책 (Cascade 옵션): 부모가 삭제될 때 자식도 같이 삭제되게 하거나(ON DELETE CASCADE), 자식의 외래 키를 Null로 만들어버리는(ON DELETE SET NULL) 등의 유연한 대처 옵션을 제공한다.

Ⅰ. 개요: 유령 부서로의 발령 (Context & Necessity)

회사에 부서_테이블직원_테이블이 있다.

  • 부서: [D1: 영업팀, D2: 개발팀]
  • 신입사원 김철수를 데이터베이스에 등록하려 한다.

초보 개발자가 실수로 쿼리를 날렸다. INSERT INTO 직원 (이름, 부서코드) VALUES ('김철수', 'D99');

  • 만약 DB가 이걸 허용한다면?
  • 나중에 사장님이 "각 부서별 인원수 좀 뽑아와"라고 할 때, D99라는 유령 부서 때문에 통계가 엉망진창이 되고 조인(JOIN) 쿼리는 에러를 뿜을 것이다.

참조 무결성은 테이블 간의 끈끈한 '관계'를 보장한다. "야! D99 부서가 부서 테이블에 없는데 어떻게 직원을 거기에 넣어! 에러 뱉어!"라고 멱살을 잡는 문지기 역할이다.

📢 섹션 요약 비유: 참조 무결성은 **'우편물 배달 규칙'**과 같습니다. 이사 간 친구에게 편지를 보낼 때, 친구가 알려준 '새 주소'가 진짜로 있는 주소(부모 테이블의 PK)여야만 우체부 아저씨가 배달(외래 키 연결)을 해줍니다. 없는 주소(D99)를 적으면 우체국에서 편지를 반송(에러)해 버리죠.


Ⅱ. 참조 무결성의 2가지 수학적 조건 ★

외래 키(FK)가 지켜야 할 두 가지 절대 규칙이다.

1. 부모에 존재하는 값일 것 (Match)

  • 자식 테이블(직원)에 값을 넣으려면, 부모 테이블(부서)의 기본 키나 유니크(Unique) 키에 그 값이 반드시 100% 존재해야 한다.

2. 예외: 아예 Null 값일 것 (Null 허용)

  • 김철수가 아직 어느 부서에 갈지 안 정해졌다면? 부서코드Null로 넣는 것은 참조 무결성 위반이 아니다!
  • "없는 부서(D99)를 적는 건 안 되지만, 아예 빈칸(Null)으로 두는 건 괜찮아." (단, 해당 외래 키 컬럼에 NOT NULL 제약조건이 안 걸려 있을 때만 가능함)

Ⅲ. 삭제/수정 시의 참조 무결성 방어 옵션

"영업팀(D1)을 없애버리자!"라고 부모 테이블에서 DELETE를 날렸다고 치자. 영업팀에 속해있던 직원들은 '부모 잃은 고아(Orphan)'가 되므로, DB 엔진은 이 삭제를 즉시 **차단(RESTRICT)**해 버린다.

이 고아들을 어떻게 처리할지 개발자는 미리 옵션으로 정해둬야 한다.

  1. RESTRICT (기본값): 자식이 한 명이라도 있으면 부모는 절대 삭제할 수 없다. (에러 발생)
  2. CASCADE (연쇄 삭제): 부모가 지워지면, 그 부모를 바라보던 자식 데이터들도 도미노처럼 다 같이 삭제된다. (위험하지만 쾌감 있음)
  3. SET NULL: 부모가 지워지면, 자식들의 외래 키 칸을 모두 Null로 싹 지워버린다. (직원 데이터는 살아남고, 부서만 미정 상태가 됨)
  4. SET DEFAULT: 부모가 지워지면, 미리 정해둔 기본값(예: '대기발령' 부서)으로 바꾼다.
┌──────────────────────────────────────────────────────────────┐
│           참조 무결성 (Referential Integrity) 위반 검사 시각화          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ [ 🏢 부서 (부모) ]        [ 👨‍💼 직원 (자식) ]                  │
│ 부서코드(PK) │ 부서명        사번(PK) │ 부서코드(FK) │ 이름        │
│ ────────┼──────       ────────┼──────────┼────        │
│   D1    │ 영업팀   ◀──┐   101  │   D1     │ 철수 🟢      │
│   D2    │ 개발팀   ◀─┐│   102  │   D2     │ 영희 🟢      │
│                   │└─   103  │  NULL    │ 민수 🟢 (소속없음)│
│                   │                                          │
│                   │ [ 🚨 위반 사례 발생! ]                      │
│                   └──   104  │   D9     │ 영수 💥 (에러!)  │
│                                                              │
│ ★ 특징: 자식은 부모에게 없는 값(D9)을 절대로 참조(가리킴)할 수 없다.          │
└──────────────────────────────────────────────────────────────┘

Ⅳ. 결론

"관계형 데이터베이스(RDB)의 '관계'를 실현하는 진짜 주인공." 우리는 RDB가 조인(JOIN)을 잘해서 관계형이라고 생각하지만, 진짜 이유는 이 참조 무결성 덕분에 데이터가 서로 모순 없이 끈끈하게 연결되어 있기 때문이다. JPA 같은 ORM 프레임워크를 쓸 때 고아 객체 제거(orphanRemoval = true) 옵션이나 폭포수 설정(cascade = CascadeType.ALL)을 고민하는 모든 과정이, 결국 데이터베이스 밑단의 이 참조 무결성 규칙을 어떻게 통제할 것인가에 대한 철학적 결정이다.


📌 관련 개념 맵

  • 관련 무결성: 개체 무결성 (Entity Integrity - 405번 문서, PK 규칙)
  • 관련 제약조건: Foreign Key (외래 키)
  • 관련 옵션: ON DELETE CASCADE, ON UPDATE SET NULL
  • 이상 현상: 이 규칙 때문에 부모를 못 지우는 현상을 방지하려면 테이블 분리(정규화)가 필수적이다.

👶 어린이를 위한 3줄 비유 설명

  1. 참조 무결성은 도서관에서 '책 빌려 가기' 규칙이에요.
  2. 도서관 목록에 있는 책(D1)이나 아예 안 빌리는 것(Null)은 괜찮아요.
  3. 하지만 도서관에 아예 없는 상상 속의 책(D99)을 빌려 갔다고 장부에 적으려고 하면, 사서 선생님이 "그런 책은 없어요!" 하고 화를 내며 막는 거랍니다!