BCNF와 그 이상
3NF까지 적용해도 여전히 이상 현상이 남는 경우가 있습니다. BCNF는 이 틈새를 메우는 더 엄격한 정규형입니다. 정규화의 궁극적 목표는 하나의 사실은 하나의 장소에만 저장하는 것인데, 3NF만으로는 이 목표를 완전히 달성하지 못하는 경우가 존재합니다.
3NF의 한계
3NF는 키가 아닌 속성이 키에 이행적으로 종속되지 않을 것을 요구합니다. 하지만 이 정의에는 허점이 있습니다. 키가 아닌 속성이 후보키의 일부를 결정하는 경우를 잡아내지 못합니다.
3NF 조건: 비주요 속성(Non-prime attribute)이 후보키에 이행 종속되지 않을 것
허점: 비주요 속성이 주요 속성(후보키 구성 속성)을 결정하는 경우
→ "후보키가 아닌 결정자"가 존재해도 3NF는 위반하지 않음
→ 이런 경우에 갱신 이상이 발생 가능
BCNF 조건: 모든 비자명(non-trivial) 함수 종속 X → Y에서 X가 슈퍼키일 것
→ 즉, 결정자는 반드시 후보키(또는 슈퍼키)여야 함
→ 3NF보다 엄격하게 모든 이상 현상을 제거BCNF (Boyce-Codd Normal Form)
BCNF의 조건: 모든 결정자가 후보키(또는 슈퍼키)여야 합니다.
3NF와의 차이는 무엇일까요? 3NF는 키가 아닌 속성 → 키가 아닌 속성 종속을 제거합니다. 하지만 키가 아닌 속성이 후보키의 일부를 결정하는 경우는 3NF로 잡히지 않습니다.
BCNF 위반 사례
수업 배정 테이블 (후보키: {학번, 과목}, {학번, 교수})
┌────────┬────────┬────────┐
│ 학번 │ 과목 │ 교수 │
├────────┼────────┼────────┤
│ 1001 │ DB │ 이교수 │
│ 1002 │ DB │ 이교수 │
│ 1001 │ OS │ 최교수 │
│ 1003 │ DB │ 박교수 │
└────────┴────────┴────────┘
제약 사항
* 한 학생은 같은 과목을 중복 수강할 수 없음
* 한 교수는 한 과목만 담당
* 한 과목은 여러 교수가 담당 가능
함수 종속
{학번, 과목} → 교수 (후보키 → 비주요 속성, OK)
{학번, 교수} → 과목 (후보키 → 비주요 속성, OK)
교수 → 과목 (비주요 속성 → 주요 속성, 문제!)
교수 → 과목이라는 종속에서, '교수'는 후보키가 아님!
→ BCNF 위반BCNF 위반이 일으키는 이상 현상
삽입 이상
'김교수'가 'AI' 과목을 담당한다는 사실을 기록하려면
→ 학번이 필요 (후보키 구성 요소)
→ 수강 학생이 없으면 기록 불가!
갱신 이상
이교수의 담당 과목이 DB → ML로 바뀌면
→ 1001, 1002 행 모두 수정 필요
→ 하나만 수정하면 불일치 발생
삭제 이상
1001 학생이 OS 수강을 취소하면
→ '최교수가 OS를 담당한다'는 정보도 사라짐BCNF 분해
결정자 '교수'를 기준으로 분해
교수-과목 테이블 (PK: 교수)
┌────────┬────────┐
│ 교수 │ 과목 │
├────────┼────────┤
│ 이교수 │ DB │
│ 최교수 │ OS │
│ 박교수 │ DB │
└────────┴────────┘
→ 교수 → 과목 종속 보존
→ '교수'가 PK(후보키)이므로 BCNF 만족
수강 테이블 (PK: {학번, 교수})
┌────────┬────────┐
│ 학번 │ 교수 │
├────────┼────────┤
│ 1001 │ 이교수 │
│ 1002 │ 이교수 │
│ 1001 │ 최교수 │
│ 1003 │ 박교수 │
└────────┴────────┘
→ BCNF 만족BCNF 분해 알고리즘
입력: 릴레이션 R과 함수 종속 집합 F
WHILE R에 BCNF 위반 종속 X → Y가 존재
1. R을 두 개로 분해:
R1 = X ∪ Y (위반 종속으로 구성된 릴레이션)
R2 = R - Y (나머지 속성)
2. R1과 R2에 대해 재귀적으로 BCNF 검사
예시
R(학번, 과목, 교수), 위반 종속: 교수 → 과목
R1 = {교수, 과목} → PK: 교수
R2 = {학번, 교수} → PK: {학번, 교수}3NF vs BCNF 상세 비교
| 구분 | 3NF | BCNF |
|---|---|---|
| 정의 | 비주요 속성이 후보키에 이행 종속하지 않음 | 모든 결정자가 슈퍼키 |
| 엄격도 | 상대적으로 느슨 | 더 엄격 |
| 포함 관계 | BCNF ⊂ 3NF (BCNF이면 반드시 3NF) | - |
| 무손실 분해 | 항상 보장 | 항상 보장 |
| 종속성 보존 | 항상 보장 | 보장되지 않을 수 있음 |
| 이상 현상 | 일부 남을 수 있음 | 모든 함수 종속 관련 이상 제거 |
| 실무 적용 | 대부분의 경우 충분 | 결정자 관계가 복잡할 때 |
원래 테이블: R(학번, 과목, 교수)
함수 종속: {학번, 과목} → 교수, 교수 → 과목
BCNF 분해 결과
R1(교수, 과목): 교수 → 과목 보존 ✓
R2(학번, 교수): {학번, 교수} → ???
{학번, 과목} → 교수 라는 종속은
R1과 R2 어느 쪽에도 직접 검증할 수 없음!
→ 종속성 보존 실패
→ "한 학생은 같은 과목을 중복 수강 불가" 제약을
단일 테이블의 UNIQUE로 강제할 수 없음
→ 두 테이블을 JOIN해야 검증 가능 → 성능 저하이런 이유로 실무에서는 3NF에서 멈추고, BCNF로 분해하지 않는 경우도 있습니다. 종속성 보존이 더 중요하다고 판단되면 3NF를 유지하면서 갱신 이상은 애플리케이션 로직으로 관리합니다.
4NF (Fourth Normal Form)
4NF는 다치 종속(Multi-Valued Dependency, MVD)을 제거합니다.
다치 종속이란
A →→ B 형태로, 하나의 A 값에 여러 B 값이 독립적으로 대응되는 관계입니다. 일반 함수 종속은 A → B(하나의 A에 하나의 B)이지만, 다치 종속은 A →→ B(하나의 A에 여러 B가 세트로)입니다.
함수 종속 (FD)
학번 → 이름
한 학번에 하나의 이름이 대응
다치 종속 (MVD)
교수 →→ 과목
한 교수에 여러 과목이 독립적으로 대응
교수 →→ 취미
한 교수에 여러 취미가 독립적으로 대응
핵심: 과목과 취미는 서로 독립적!
이교수의 과목 = {DB, OS}
이교수의 취미 = {등산, 독서}
→ 이 두 집합은 서로 관계없이 독립적으로 존재
→ 조합하면 2×2 = 4행이 됨 (불필요한 중복)4NF 위반 사례
교수-과목-취미 (BCNF이지만 4NF 위반)
┌────────┬────────┬────────┐
│ 교수 │ 과목 │ 취미 │
├────────┼────────┼────────┤
│ 이교수 │ DB │ 등산 │
│ 이교수 │ DB │ 독서 │
│ 이교수 │ OS │ 등산 │
│ 이교수 │ OS │ 독서 │
└────────┴────────┴────────┘
다치 종속
교수 →→ 과목 (과목과 취미는 독립적)
교수 →→ 취미
문제
이교수가 '요리'라는 취미를 추가하면
→ DB-요리, OS-요리 두 행을 모두 추가해야 함
→ 중복 데이터의 기하급수적 증가4NF 분해
교수-과목 (PK: {교수, 과목})
┌────────┬────────┐
│ 교수 │ 과목 │
├────────┼────────┤
│ 이교수 │ DB │
│ 이교수 │ OS │
└────────┴────────┘
교수-취미 (PK: {교수, 취미})
┌────────┬────────┐
│ 교수 │ 취미 │
├────────┼────────┤
│ 이교수 │ 등산 │
│ 이교수 │ 독서 │
└────────┴────────┘
4NF 분해 규칙
BCNF를 만족하고, 비자명 다치 종속 X →→ Y에서
X가 슈퍼키이면 4NF 만족
X가 슈퍼키가 아니면 X ∪ Y와 R - Y로 분해5NF (Fifth Normal Form)
5NF(Project-Join Normal Form, PJ/NF)는 조인 종속(Join Dependency)을 제거합니다.
조인 종속이란
릴레이션 R이 R1, R2, ..., Rn으로 분해된 뒤, 이들을 자연 조인하면 원래 R이 정확히 복원되는 성질입니다. 2개 테이블로 분해해서는 정보 손실 없이 분해할 수 없지만, 3개 이상으로 분해하면 가능한 경우가 있습니다.
공급자-부품-프로젝트 (SPJ)
┌──────┬──────┬──────────┐
│공급자│ 부품 │ 프로젝트 │
├──────┼──────┼──────────┤
│ S1 │ P1 │ J1 │
│ S1 │ P2 │ J1 │
│ S2 │ P1 │ J1 │
│ S1 │ P1 │ J2 │
└──────┴──────┴──────────┘
의미: "공급자 S가 부품 P를 공급하고,
공급자 S가 프로젝트 J에 참여하고,
프로젝트 J가 부품 P를 사용한다"면
→ "공급자 S가 부품 P를 프로젝트 J에 공급한다"
이 제약이 성립하면 3개 테이블로 분해 가능
SP(공급자, 부품): S가 P를 공급 가능
SJ(공급자, 프로젝트): S가 J에 참여
PJ(부품, 프로젝트): J가 P를 사용
SP ⋈ SJ ⋈ PJ = SPJ (원래 릴레이션 복원)SP (PK: {공급자, 부품})
┌──────┬──────┐
│공급자│ 부품 │
├──────┼──────┤
│ S1 │ P1 │
│ S1 │ P2 │
│ S2 │ P1 │
└──────┴──────┘
SJ (PK: {공급자, 프로젝트})
┌──────┬──────────┐
│공급자│ 프로젝트 │
├──────┼──────────┤
│ S1 │ J1 │
│ S1 │ J2 │
│ S2 │ J1 │
└──────┴──────────┘
PJ (PK: {부품, 프로젝트})
┌──────┬──────────┐
│ 부품 │ 프로젝트 │
├──────┼──────────┤
│ P1 │ J1 │
│ P2 │ J1 │
│ P1 │ J2 │
└──────┴──────────┘5NF는 이론적으로는 흥미롭지만, 실무에서 직접 적용하는 경우는 극히 드뭅니다. 조인 종속을 식별하는 것 자체가 매우 어렵고, 과도한 분해는 조인 비용을 증가시킵니다.
정규형의 포함 관계
1NF ⊃ 2NF ⊃ 3NF ⊃ BCNF ⊃ 4NF ⊃ 5NF
모든 5NF 릴레이션은 4NF를 만족하고,
모든 4NF 릴레이션은 BCNF를 만족하고,
모든 BCNF 릴레이션은 3NF를 만족하고,
...
역은 성립하지 않음
3NF인데 BCNF가 아닌 릴레이션이 존재
BCNF인데 4NF가 아닌 릴레이션이 존재정규화 분해의 두 가지 기준
정규화로 테이블을 분해할 때는 두 가지가 보장되어야 합니다.
무손실 조인 분해 (Lossless Join Decomposition)
분해된 테이블들을 자연 조인하면 원래 테이블이 정확히 복원되어야 합니다. 잘못 분해하면 조인 시 원래 없던 행이 생기는 가짜 튜플(Spurious Tuple) 문제가 발생합니다.
R(A, B, C)를 R1(A, B)과 R2(B, C)로 분해할 때:
B → A 또는 B → C가 성립하면 무손실 조인 보장
일반적으로
R1 ∩ R2의 속성이 R1이나 R2의 슈퍼키이면
→ 무손실 조인 분해
예시
R(학번, 이름, 학과), FD: 학번 → 이름, 학번 → 학과
R1(학번, 이름), R2(학번, 학과)
→ R1 ∩ R2 = {학번}
→ 학번은 R1과 R2 모두에서 키
→ 무손실 ✓종속성 보존 분해 (Dependency Preserving Decomposition)
원래 릴레이션의 모든 함수 종속이 분해된 릴레이션들에서 직접 검증 가능해야 합니다. 종속성 보존이 안 되면, 무결성 검증을 위해 조인이 필요해져 성능이 저하됩니다.
R(A, B, C), FD: {A → B, B → C, A → C}
R1(A, B)과 R2(B, C)로 분해
R1에서 A → B 검증 가능 ✓
R2에서 B → C 검증 가능 ✓
A → C는 R1의 A → B와 R2의 B → C의 이행으로 유도 가능 ✓
→ 종속성 보존 ✓┌───────────────┬────────────────┬──────────────────┐
│ 정규화 │ 무손실 조인 │ 종속성 보존 │
├───────────────┼────────────────┼──────────────────┤
│ 3NF 분해 │ 항상 보장 │ 항상 보장 │
│ BCNF 분해 │ 항상 보장 │보장 안 될 수 있음│
│ 4NF 분해 │ 항상 보장 │보장 안 될 수 있음│
└───────────────┴────────────────┴──────────────────┘실무에서 어디까지 정규화하는가
| 상황 | 권장 정규형 | 이유 |
|---|---|---|
| 일반적인 OLTP 시스템 | 3NF | 대부분의 이상 현상 제거, 종속성 보존 |
| 복잡한 업무 규칙 | BCNF 검토 | 결정자-피결정자 관계가 복잡할 때 |
| 데이터 웨어하우스/분석 | 반정규화 (스타 스키마) | 조인 최소화, 조회 성능 우선 |
| 시험/이론 | 5NF까지 | 4NF, 5NF 개념 문제 출제 |
실무 정규화 판단 기준
1NF: 모든 속성이 원자값인가?
├─ NO → 1NF 적용
└─ YES → 계속
2NF: 부분 종속이 있는가? (복합키가 있을 때만 해당)
├─ YES → 2NF 적용 (부분 종속 분리)
└─ NO → 계속
3NF: 이행 종속이 있는가?
├─ YES → 3NF 적용 (이행 종속 분리)
└─ NO → 계속
BCNF: 후보키가 아닌 결정자가 있는가?
├─ YES → 종속성 보존 검토 후 판단
│ ├─ 보존 가능 → BCNF 적용
│ └─ 보존 불가 → 3NF 유지 + 앱 로직으로 보완
└─ NO → 현재 상태 유지 (대부분 여기서 끝)과도한 정규화의 문제
테이블 수 증가
→ 단순 조회도 여러 테이블 JOIN 필요
→ 쿼리 복잡도 증가
→ 개발 생산성 저하
조인 비용
→ 테이블 분리가 많을수록 JOIN 횟수 증가
→ 대량 데이터에서 조인 성능 저하
→ 특히 OLAP 환경에서 치명적
유지보수
→ 엔티티 간 관계 파악이 어려워짐
→ 데이터 입력/수정 시 여러 테이블 동시 처리 필요
→ 외래키 제약이 많아져 데이터 마이그레이션 복잡정규화 연습 문제
R(A, B, C, D)
후보키: {A, B}
함수 종속: {A, B} → C, {A, B} → D, C → D
질문: 이 릴레이션은 BCNF인가?
풀이
{A, B} → C: 결정자 {A, B}는 후보키 → OK
{A, B} → D: 결정자 {A, B}는 후보키 → OK
C → D: 결정자 C는 후보키가 아님! → BCNF 위반!
분해
R1(C, D): C → D 보존, PK = C → BCNF ✓
R2(A, B, C): {A, B} → C 보존, PK = {A, B} → BCNF ✓
검증
R1 ⋈ R2: 공통 속성 C, R1에서 C는 키 → 무손실 조인 ✓
종속성 보존: {A,B}→C는 R2에서, C→D는 R1에서 직접 검증 가능 ✓R(학번, 과목코드, 교수명, 학과)
후보키: {학번, 과목코드}
함수 종속
{학번, 과목코드} → 교수명
교수명 → 학과, 과목코드
3NF 검사
교수명 → 학과: 비주요 → 비주요 이행 종속?
학번, 과목코드 → 교수명 → 학과
→ 이행 종속! 3NF 위반!
먼저 3NF로 분해
R1(교수명, 학과, 과목코드): 교수명 → {학과, 과목코드}
R2(학번, 교수명): {학번, ?} → 교수명?
실제로는
R1(교수명, 과목코드, 학과): PK = 교수명
R2(학번, 교수명): PK = {학번, 교수명}
→ 3NF이자 BCNF ✓R(교수, 과목, 위원회)
후보키: {교수, 과목, 위원회} (전체가 키)
다치 종속:
교수 →→ 과목
교수 →→ 위원회
질문: 현재 정규형은? 위반된 정규형은?
풀이
후보키는 전체 속성 집합 → 부분 종속, 이행 종속 없음 → 3NF ✓
모든 결정자가 슈퍼키인가?
교수 →→ 과목에서 교수는 슈퍼키 아님 → 4NF 위반
BCNF는? 함수 종속이 없으므로 BCNF ✓ (다치 종속은 BCNF 판단과 무관)
현재: BCNF이지만 4NF 위반
분해
R1(교수, 과목): PK = {교수, 과목}
R2(교수, 위원회): PK = {교수, 위원회}
→ 4NF ✓정리
| 정규형 | 핵심 조건 | 제거 대상 |
|---|---|---|
| 1NF | 원자값 | 반복 그룹, 복합 값 |
| 2NF | 완전 종속 | 부분 종속 |
| 3NF | 비이행 종속 | 이행 종속 |
| BCNF | 모든 결정자가 슈퍼키 | 후보키 아닌 결정자 |
| 4NF | 다치 종속 제거 | 독립적 다중값 관계 |
| 5NF | 조인 종속 제거 | 3개 이상 분해 필요 사례 |
정규화는 데이터 무결성을 위한 것이고, 반정규화는 성능을 위한 것입니다. 실무에서는 3NF까지 적용하고, BCNF 위반이 발견되면 종속성 보존 여부를 검토한 뒤 적용 여부를 결정하는 접근이 가장 합리적입니다. 4NF와 5NF는 시험에서 개념을 묻는 경우가 있으므로 정의와 예시를 확실히 이해해두어야 합니다.
다음 절에서 반정규화를 다루겠습니다.