반정규화와 성능 모델링
정규화된 모델을 성능 요구에 맞게 조정하는 반정규화의 목적, 유형, 위험을 시험 기준으로 정리합니다.
출제 빈도 ★★★☆☆ 관련 문제 2개 |
반정규화중복분할 반정규화는 정규화의 반대가 아닙니다
반정규화는 정규화를 무시하는 설계가 아니라, 정규화된 모델에서 성능 문제를 해결하기 위해 의도적으로 중복이나 구조 변경을 허용하는 작업입니다.
초보 학습자가 흔히 혼동하는 부분은 “조인이 많으면 곧 반정규화”라고 생각하는 것입니다. 시험에서는 보통 다음 순서를 올바른 접근으로 봅니다.
- 먼저 정규화로 데이터 중복과 이상 현상을 줄입니다.
- 실제 조회 패턴과 성능 병목을 확인합니다.
- 조인, 집계, 대량 조회 비용이 반복적으로 문제인지 판단합니다.
- 필요한 범위에서 반정규화를 적용합니다.
- 중복 데이터의 정합성을 유지할 방법을 함께 설계합니다.
반정규화가 필요한 상황
| 상황 | 예 | 고려할 조정 |
|---|---|---|
| 조인이 지나치게 빈번함 | 매 화면마다 고객명과 등급을 주문과 함께 조회 | 중복 컬럼 추가 |
| 집계 비용이 큼 | 매번 주문상세를 합산해 총주문금액 계산 | 집계 컬럼 또는 요약 테이블 |
| 이력 조회가 많음 | 특정 시점의 상태를 자주 조회 | 이력 테이블 분리 |
| 테이블이 너무 큼 | 월별 대량 거래 데이터 | 파티션 또는 테이블 분할 |
성능 개선 효과만 보고 반정규화를 적용하면 갱신 이상이 생길 수 있습니다. 예를 들어 주문 테이블에 고객명을 중복 저장하면 고객명이 바뀔 때 과거 주문의 고객명을 함께 바꿀지, 당시 이름으로 남길지 업무 규칙을 정해야 합니다.
정규화 설계
고객(고객번호, 고객명)
주문(주문번호, 고객번호, 주문일)
- 중복이 없습니다.
- 고객명 조회 시 조인이 필요합니다.
- 고객명 변경이 한 번에 반영됩니다.
반정규화 설계
고객(고객번호, 고객명)
주문(주문번호, 고객번호, 고객명, 주문일)
- 주문에 고객명이 중복 저장됩니다.
- 조인 없이 주문 화면을 구성할 수 있습니다.
- 고객명 변경 시 동기화 규칙이 필요합니다.
반정규화 유형
컬럼 반정규화
다른 테이블에서 가져와야 하는 값을 현재 테이블에 중복 저장합니다.
주문(주문번호, 고객번호, 고객명, 주문일)
고객명은 고객 테이블에도 있지만 주문 조회 성능이나 당시 고객명 보존이 필요한 경우 주문에 함께 저장할 수 있습니다.
테이블 반정규화
자주 함께 조회되는 테이블을 병합하거나, 자주 필요한 집계 결과를 별도 테이블로 만듭니다.
일별상품매출(매출일자, 상품번호, 판매수량, 판매금액)
매번 주문상세를 모두 읽어 집계하지 않고 요약 테이블을 조회합니다.
관계 반정규화
멀리 떨어진 관계를 빠르게 찾기 위해 중간 경로를 줄입니다.
예를 들어 고객 → 주문 → 배송 관계에서 배송 조회가 고객 기준으로 빈번하다면 배송 테이블에 고객번호를 추가하는 방식을 고려할 수 있습니다.
반정규화의 위험
| 위험 | 설명 |
|---|---|
| 데이터 불일치 | 같은 의미의 값이 여러 곳에 저장되어 서로 달라질 수 있습니다 |
| 갱신 비용 증가 | 한 값을 바꿀 때 여러 테이블이나 컬럼을 함께 바꿔야 합니다 |
| 설계 복잡도 증가 | 어떤 값이 원본이고 어떤 값이 중복인지 관리해야 합니다 |
| 업무 규칙 혼란 | 과거 값을 보존할지 최신 값으로 맞출지 결정이 필요합니다 |
시험장에서 판단하는 기준
- 반정규화는 성능 개선을 위한 선택지이며 기본 설계 원칙은 아닙니다.
- 반정규화 전에 정규화와 성능 병목 확인이 먼저 이루어져야 합니다.
- 조회 성능은 좋아질 수 있지만 입력, 수정, 삭제의 정합성 관리 비용이 늘어납니다.
- 중복을 허용한다면 동기화 규칙이 필요합니다.
한 문장 요약
반정규화는 성능을 위해 중복을 허용하는 대신, 정합성 관리 책임을 함께 지는 설계입니다.