정규화
DB를 join하다보면 데이터 중복이 생겨 수정이 어려워지기도 한다.
이런 상황에 데이터 정규화(Normalization)가 필요하다.
Decomposition
테이블을 두 테이블로 나눠서 중복값을 제거하는 방법이다.
데이터 분할 시 손실이 발생하는 경우 lossy decomposition 이라고 한다.
Normalization theory
- relation R이 좋은 상태인지 판별한다.
- R이 좋은 상태가 아니라면 R1, R2, ...로 분해한다. 각 요소는 좋은 테이블이어야 하고 손실이 발생하면 안 된다.
이 이론은 functional dependency(함수적 종속성), multivalued dependency(다중값 종속성)를 따른다.
Functional dependency
원소 α, β가 모두 relation R에 속할 때 t1[α] = t2[α] ⇒ t1[β] = t2[β] 이면 α가 β를 결정한다.
이것을 α → β 로 나타내고 함수적 종속성 이라고 한다.
만약 A → B이고 B → C 이면 A → C라고 할 수 있다.
Trivial FD
다음과 같은 경우에 FD는 항상 성립한다.
- ID, name → ID
- name → name
이렇게 DB 설계 상 무조건 함수적 종속성이 있는 경우를 trivial 하다고 한다.
Lossless decomposition
손실 없이 테이블을 분해하기 위해서는 다음 조건 중 하나 이상을 만족해야 한다.
- R1 ∩ R2 → R1
- R1 ∩ R2 → R2
R1과 R2에 공통되는 속성이 있어야 하고, 공통되는 속성이 두 테이블 중 적어도 하나의 key인 경우 손실 없는 분해가 가능하다.
정규화 형식
1NF
원자값만을 허용한다. 한 셀에는 데이터 하나만 들어갈 수 있으며 리스트는 안 된다.
2NF
부분 함수의 종속을 제거한다.
1NF를 먼저 만족해야 하며, 기본키가 복합키인 경우 일부에만 의존하는 컬럼을 제거한다.
예를 들어 다음과 같은 테이블이 있다고 해보자.
| 학번 + 과목 | 교수명 | |
|---|
| 001, 과학 | 김교수 | |
| 001, 수학 | 김교수 | |
이 경우 교수명은 학번만 보고도 알 수 있으며 과목 데이터에는 영향을 끼치지 않는다.
따라서 교수명을 다른 테이블로 분리하는 것이 좋다.
BCNF
릴레이션 R의 모든 함수 종속 a -> b에 대해 a가 반드시 super 키여야 한다.
릴레이션 R의 모든 함수 종속 a -> b에 대해
- a -> b 가 trivial이다.
즉 a이면 무조건 b인 관계가 성립해야 한다.
- a가 R의 superkey이다.
- b - a 의 모든 속성이 R의 candidate key에 포함됨
셋 중 하나를 만족하면 3NF이다.
풀어서 말하면 키가 아닌 속성이 또 다른 속성을 결정하면 안 된다.
BCNF에서 a가 무조건 superkey여야 하는 조건을 완화하면 3NF가 된다.
성능 비교
BCNF는 3NF에 비해 중복이 없기 때문에 대체로 좋지만, BCNF에서 종속성(dependency)이 보존되지 않는 경우가 종종 발생하는데 이 때는 3NF가 더 안정적이다.
ER 모델과 정규화
E-R 다이어그램을 제대로 구성하면 정규화가 필요 없다. 하지만 실제로는 속성 사이에 함수적 의존성이 생기는 경우가 많아서 테이블을 나누는 편이 낫다.
📘 Chapter 7: Normalization 요약 & 핵심 정리
🧭 1. 개요: 정규화란?
-
목적: 중복 최소화, 이상(anomalies) 방지, 데이터 무결성 유지
-
수단: 함수적 종속(Functional Dependencies), 다값 종속(MVD) 등을 기반으로 릴레이션을 **좋은 형태로 분해(decomposition)**함
-
좋은 설계 기준:
- 중복 없음
- NULL 최소화
- 무손실 분해 (Lossless Join)
- 종속성 보존 (Dependency Preservation)
🔍 2. 반복/중복 문제와 분해
❌ 중복 문제
in_dep(instructor + department) 스키마처럼 두 테이블을 합치면 중복, NULL 문제 발생
✅ 해결책: 분해
- 중복을 피하려면 다시 instructor, department로 분해
- 주의: 분해한다고 다 좋은 건 아님 (정보 손실 가능)
🧪 3. 손실 없는 분해 (Lossless Decomposition)
🔗 4. 함수적 종속 (Functional Dependency)
- 정의: α → β: 어떤 튜플 두 개가 α에서 같다면, β도 같아야 함
- 예: 학번 → 이름, 과목 등
- 종류: 자명한 종속(β ⊆ α), 비자명한 종속
- 폐포(F⁺): 주어진 종속으로부터 유추 가능한 모든 종속 집합
🗝️ 5. 키와 함수적 종속
- 슈퍼키: 모든 속성을 결정할 수 있는 키
- 후보키: 최소 슈퍼키
- 함수적 종속은 키가 아닌 속성 간 제약도 표현 가능
✅ 1NF: 원자값만 허용 (리스트/집합 금지)
✅ 2NF: 부분 함수 종속 제거 (복합키일 때 키의 일부에만 종속된 속성 분리)
✅ 3NF: 이행 종속 제거 + 다음 중 하나라도 만족해야 함
- α → β가 자명
- α가 슈퍼키
- β−α의 각 속성이 후보키에 포함
모든 함수적 종속 α → β에 대해, α는 반드시 슈퍼키
3NF보다 더 강력하지만, 종속성 보존이 어려울 수 있음
🔄 7. 3NF vs BCNF 비교
| 항목 | 3NF | BCNF |
|---|
| 종속성 보존 | 항상 가능 | 불가능할 수도 있음 |
| 이상 제거 | 대부분 제거 | 완전 제거 |
| 분해 필요 여부 | 유연함 | 엄격함 |
| 성능/단순성 | 실용적 | 이상적 (완벽 무결성 지향) |
🧪 8. 분해 알고리즘 (3NF 예시)
입력:
-
cust_banker_branch(customer_id, employee_id, branch_name, salary, type)
-
함수 종속:
- customer_id, employee_id → type
- employee_id → branch_name, salary
- customer_id, branch_name → employee_id
결과:
- (customer_id, employee_id, type)
- (employee_id, branch_name, salary)
- (customer_id, branch_name, employee_id)
→ 무손실 + 종속성 보존
🌀 9. 4NF와 다중값 종속 (MVD)
- 다중값 종속 α ↠ β: α가 같으면 β의 가능한 조합은 모두 존재해야 함
- BCNF를 만족하고 다중값 종속도 없음 → 4NF
- 예: instructor가 여러 자녀와 여러 전화번호를 가질 수 있는 경우
🧬 10. 기타 고급 정규형
- 5NF (PJNF): Join Dependency 고려
- DKNF: 도메인 + 키 기반 제약
→ 현실에서는 3NF 또는 BCNF + 경우에 따라 4NF까지만 사용함
🏗️ 11. ER 모델과 정규화
- 잘 설계된 ER 다이어그램 → 정규화 거의 불필요
- 실제 설계는 불완전할 수 있으므로 정규화로 보완 필요
🛠️ 12. 성능을 위한 비정규화 (Denormalization)
- 조회 성능 향상 위해 정규형을 일부 깨뜨리기도 함
- 대안: Materialized View 사용 (성능 향상 + 무결성 유지)
🚫 13. 잘못된 설계 예
- 테이블을 연도별로 나누기 (
earnings_2024, earnings_2025, ...)
→ 쿼리 어려움, 스키마 관리 복잡
→ 이런 Crosstab 설계는 피해야 함
🎯 최종 목표
정규화 과정은 다음 3가지 목표를 만족하는 방향으로 이뤄져야 해:
- 모든 릴레이션이 "좋은 형식" (정규형)에 속함
- 무손실 분해
- 가능하면 종속성도 보존
📌 핵심 요약 키워드
- 1NF: 원자값
- 2NF: 부분 종속 제거
- 3NF: 이행 종속 제거
- BCNF: 슈퍼키 기반
- 4NF: 다중값 종속 제거
- 무손실 분해 vs 종속성 보존
- 정규화 vs 비정규화