정규화와 반정규화 판단 기준
한 줄 정의
정규화는 중복을 제거하고 데이터 정합성을 보장하도록 테이블을 분리하는 설계이고, 반정규화는 조회 성능을 위해 의도적으로 중복을 허용하는 설계다.
실무에서 왜 중요한가
- 정규화를 모르면 같은 데이터가 여러 곳에 퍼져서 수정 시 불일치가 발생한다.
- 과도한 정규화는 JOIN이 많아져 조회 성능이 떨어진다.
- 반정규화를 아무 기준 없이 하면 데이터 불일치와 갱신 비용이 늘어난다.
- 정규화/반정규화의 기준 없이 설계하면 나중에 구조 변경 비용이 커진다.
정규화 단계
제1정규형 (1NF)
규칙: 모든 컬럼이 원자값(atomic value)을 가져야 한다. 한 셀에 여러 값이 들어가면 안 된다.
❌ 비정규
| user_id | phones |
|---------|---------------------|
| 1 | 010-1111, 010-2222 |
✅ 1NF
| user_id | phone |
|---------|------------|
| 1 | 010-1111 |
| 1 | 010-2222 |
제2정규형 (2NF)
규칙: 1NF + 부분 함수 종속 제거. 기본키의 일부에만 종속되는 컬럼을 분리한다.
❌ 부분 종속 (복합키: order_id + product_id)
| order_id | product_id | product_name | quantity |
|----------|------------|--------------|----------|
product_name은 product_id에만 종속 → 부분 종속
✅ 2NF: 분리
Orders: | order_id | product_id | quantity |
Products: | product_id | product_name |
제3정규형 (3NF)
규칙: 2NF + 이행 함수 종속 제거. 기본키가 아닌 컬럼이 다른 비키 컬럼을 결정하면 분리한다.
❌ 이행 종속
| employee_id | department_id | department_name |
department_name은 department_id에 종속 (employee_id → department_id → department_name)
✅ 3NF: 분리
Employees: | employee_id | department_id |
Departments: | department_id | department_name |
정리
| 단계 | 제거 대상 | 핵심 |
|---|---|---|
| 1NF | 반복 그룹, 비원자값 | 한 셀에 하나의 값 |
| 2NF | 부분 함수 종속 | 복합키 일부에만 종속되는 컬럼 분리 |
| 3NF | 이행 함수 종속 | 비키 컬럼 간 종속 제거 |
실무에서는 3NF까지 적용하는 것이 일반적이다. BCNF 이상은 특수한 경우에만 고려한다.
반정규화 (Denormalization)
정규화된 테이블에 의도적으로 중복을 추가하여 조회 성능을 높이는 기법이다.
반정규화 기법
| 기법 | 설명 | 예시 |
|---|---|---|
| 컬럼 중복 | 자주 조회하는 컬럼을 다른 테이블에 복사 | 주문 테이블에 user_name 추가 |
| 파생 컬럼 | 계산 결과를 미리 저장 | order_count, total_amount |
| 테이블 병합 | 항상 함께 조회하는 1:1 테이블 합치기 | user + user_profile 병합 |
| 요약 테이블 | 집계 결과를 별도 테이블에 저장 | 일별 매출 요약 |
반정규화 판단 기준
| 조건 | 판단 |
|---|---|
| 조회가 압도적으로 많고, 쓰기가 드물다 | 반정규화 고려 |
| JOIN이 3개 이상이고 데이터가 크다 | 반정규화 고려 |
| 데이터 변경 시 여러 곳을 함께 갱신해야 한다 | 반정규화 비용 높음 (주의) |
| 실시간 정합성이 반드시 필요하다 | 정규화 유지 |
| 보고서/대시보드용 조회가 느리다 | 요약 테이블 고려 |
실무 트레이드오프
정규화 ←───────────────���──────────→ 반정규화
정합성 높음 조회 성능 높음
JOIN 많음 중복 데이터
갱신 비용 낮음 갱신 비용 높음
저장 공간 적음 저장 공간 큼
실무 판단 흐름
- 기본은 3NF로 설계한다.
- 성능 문제가 측정으로 확인되면 반정규화를 검토한다.
- 반정규화 시 갱신 정합성 전략을 함께 설계한다 (이벤트, 배치, 트리거 등).
- 반정규화한 컬럼/테이블을 문서로 남긴다.
자주 나는 실수
- 성능 문제가 없는데 “나중에 느려질까봐” 미리 반정규화한다.
- 반정규화한 컬럼의 갱신 전략을 설계하지 않아서 데이터 불일치가 발생한다.
- 정규화를 안 해서 같은 데이터를 여러 곳에서 수정해야 하는 구조가 된다.
- 기술 질문에서 “무조건 정규화” 또는 “무조건 반정규화”로 답변한다.
핵심 요약
정규화는 중복을 제거하고 정합성을 보장하는 설계로, 실무에서는 3NF까지 적용하는 것이 일반적입니다. 반정규화는 조회 성능을 위해 의도적으로 중복을 추가하는 것으로, 측정된 성능 문제가 있을 때 검토합니다.
반정규화할 때는 반드시 갱신 정합성 전략(이벤트, 배치 등)을 함께 설계해야 합니다. 질문을 받으면 “기본은 정규화, 측정된 병목이 있으면 반정규화하고, 갱신 전략을 함께 설계한다”가 안전한 답변입니다.
꼬리 질문
정규화와 반정규화를 선택하는 기준은?
기본은 3NF로 설계하고, 실제 조회 성능이 문제될 때 반정규화를 검토합니다. 반정규화는 “쓰기 비용을 높여서 읽기 비용을 낮추는” 트레이드오프입니다.
반정규화한 데이터의 정합성은 어떻게 유지하는가?
이벤트 기반 갱신, 배치 동기화, DB 트리거 등을 사용합니다. 어떤 방식이든 “원본이 바뀌면 복사본도 반드시 갱신된다”는 보장이 필요합니다.
1NF, 2NF, 3NF를 한 문장씩 설명하면?
1NF: 한 셀에 하나의 값. 2NF: 복합키 일부에만 종속되는 컬럼 분리. 3NF: 비키 컬럼 간의 종속 제거.