정규화(normalization)는 테이블을 나눠 데이터 중복을 줄이고 삽입·삭제·갱신 이상을 막는 설계 과정이다. 각 단계(정규형, normal form)는 특정한 종속 관계를 없앤다. "도부이결다조"는 각 단계의 앞 글자를 딴 암기법이다.
| 단계 | 조건 | 없애는 것 |
|---|---|---|
| 1NF (도) | 모든 값이 원자값 | 한 칸에 여러 값 |
| 2NF (부) | 1NF + 부분 함수 종속 없음 | 복합키의 일부에만 종속 |
| 3NF (이) | 2NF + 이행 함수 종속 없음 | 키가 아닌 컬럼을 거친 종속 |
| BCNF(Boyce-Codd Normal Form) (결) | 모든 결정자가 후보키 | 후보키가 아닌 결정자 |
| 4NF (다) | BCNF + 다치 종속 없음 | 독립적인 다중값의 조합 |
| 5NF (조) | 4NF + 조인 종속 없음 | 분해·재조인 시 손실 |
예로 보기
- 1NF 위반: 전화번호 칸에
010-1111-1111, 010-2222-2222→ 행을 나누거나 전화번호 테이블로 분리 - 2NF 위반: 수강(학번+과목코드 → 성적) 테이블에 학생 이름이 있다. 이름은 학번에만 종속 → 학생 테이블로 분리
- 3NF 위반: 사원(사번 → 부서코드 → 부서명) → 부서명은 부서 테이블로
- BCNF 위반: 수강(학번, 과목, 교수)에서 "교수 → 과목"인데 교수가 후보키가 아님 → (학번, 교수)와 (교수, 과목)으로 분해
- 4NF 위반: 학생의 동아리와 수강과목이 서로 무관한데 한 테이블에 모든 조합이 생김 → 두 테이블로
이상 현상
중복이 있으면 부서명 하나를 바꿀 때 여러 행을 고쳐야 하고(갱신 이상, update anomaly), 사원이 없으면 부서를 저장할 수 없으며(삽입 이상, insertion anomaly), 마지막 사원을 지우면 부서 정보까지 사라진다(삭제 이상, deletion anomaly).
어디까지 하나
실무에서는 보통 3NF나 BCNF까지 한다. 더 나누면 조인이 늘어 조회가 느려질 수 있어, 읽기가 중요한 곳은 의도적으로 비정규화(denormalization)하기도 한다. 그때는 중복된 값을 맞추는 비용을 대신 진다(DB 인덱스와 트레이드오프의 트레이드오프와 같다). 코드에서 같은 지식을 한 곳에만 두라는 DRY 원칙와 같은 생각이다.