반정규화와 성능 근거
반정규화는 정규화 오류를 방치하는 것이 아니라 측정된 병목을 해결하기 위해 중복·통합·파생·요약 구조를 의도적으로 도입하는 물리 설계 결정입니다. 적용 전 대안을 비교하고 읽기 이득과 갱신·정합성 비용을 정량화한 뒤 동기화·복구·철회 기준을 정의해야 합니다.
핵심 요약
반정규화는 “조인이 많다”는 인상이나 개발 편의를 근거로 수행하지 않는다. 정상화된 기준 구조에서 핵심 SQL의 응답시간·논리 I/O·호출빈도·반환건수와 DML 부하를 측정하고, 인덱스·SQL 개선·접근 경로·캐시·요약 처리 등 대안을 검토한 뒤에도 목표를 만족하지 못할 때 선택한다. 중복된 값에는 반드시 원천, 갱신 책임, 허용 지연, 오류 탐지, 재생성 방법이 있어야 한다.
학습 목표
- 반정규화의 전제와 적용 판단 순서를 설명한다.
- 테이블 통합·분할, 중복 컬럼, 파생값, 요약 구조의 효과와 비용을 비교한다.
- 성능 이득과 정합성·DML·저장 비용을 정량적으로 평가한다.
- 동기화·오류 복구·재검증·철회 기준을 설계한다.
1. 반정규화의 전제
반정규화는 다음 조건을 갖춰야 한다.
- 기준이 되는 정규화 구조와 업무 원천이 명확하다.
- 병목 SQL·프로세스와 목표 성능이 측정되어 있다.
- 조인 방식, 인덱스, SQL, 통계, 캐시, 배치 주기 등 덜 위험한 대안을 검토했다.
- 읽기 이득이 갱신·저장·운영 비용보다 크다는 근거가 있다.
- 중복값의 정합성 통제와 장애 복구 방법이 있다.
- 데이터·부하가 바뀔 때 재평가하는 기준이 있다.
정규화를 하지 않은 초기 구조를 “반정규화”라고 부를 수 없다. 반정규화는 종속 관계를 이해하고 통제한 상태에서 의도적으로 구조를 변경한 것이다.
2. 대표 유형
2.1 테이블 통합
항상 1:1로 함께 생성·조회되고 생명주기와 보안 수준이 같은 두 테이블을 합치면 조인을 줄일 수 있다.
- 이득: 조인·객체 관리 감소
- 비용: 행 폭 증가, NULL 증가, 서로 다른 보존·보안·갱신 주기 결합
- 주의: 단순히 테이블 수가 많다는 이유로 합치지 않는다.
2.2 테이블 분할
한 테이블에서 매우 자주 조회되는 좁은 속성과 드물게 조회되는 큰 속성을 수직 분리하거나, 업무 처리 특성이 크게 다른 행 집합을 별도 구조로 분리할 수 있다.
- 이득: 핵심 행 폭·I/O 감소, 경합 분리
- 비용: 조인·동기화·전체 조회 복잡성
- 경계: 파티션 구현 방식의 상세는 별도 성능 설계 범위이며 여기서는 구조적 목적만 다룬다.
2.3 중복 컬럼
부모나 관련 테이블의 값을 자식에 복제한다.
원천: 고객.고객등급코드
중복: 주문.주문시점고객등급코드
주문 당시 사실을 보존하는 스냅샷이면 단순 성능 중복과 다른 업무 의미를 가질 수 있다. 현재 고객등급을 편의상 복제한다면 고객 변경 시 모든 주문을 갱신할 것인지, 과거 주문을 바꾸지 않을 것인지 명확히 해야 한다.
2.4 파생 컬럼
합계·잔액·건수·상태 요약을 저장한다.
- 원천 행 변경과 같은 트랜잭션에서 갱신할지
- 비동기 집계로 지연을 허용할지
- 재계산 시점과 반올림·규칙 버전을 어떻게 보존할지
- 음수 잔액·중복 집계 같은 오류를 어떻게 탐지할지
2.5 요약·집계 테이블
상세 대량 집계를 일·월·고객·상품 단위로 미리 계산한다.
- 이득: 대시보드·보고서 집계 비용 감소
- 비용: 적재 지연, 늦게 도착한 데이터 재집계, 상세-요약 불일치
- 통제: 집계 기준시각, 완료 상태, 재처리 키, 상세 합계 대조
3. 적용 전 대안과 비교
| 문제 | 먼저 검토할 대안 | 반정규화 후보 |
|---|---|---|
| 선택적 조회가 느림 | 조건·통계·인덱스·SQL 개선 | 자주 쓰는 속성 중복 또는 좁은 조회 구조 |
| 반복 집계가 비쌈 | 집계 SQL·실행주기·캐시 검토 | 요약 테이블·저장 파생값 |
| 1:1 조인이 항상 발생 | 조인 계획·뷰 검토 | 테이블 통합 |
| 매우 넓은 행의 일부만 조회 | 컬럼 선택·LOB 처리 검토 | 수직 분할 |
| 원격 데이터 조인이 병목 | 통신·배치·캐시 검토 | 통제된 로컬 복제 |
대안의 존재가 반정규화를 금지한다는 뜻은 아니다. 각 대안의 성능·정합성·운영 비용을 같은 부하 조건에서 비교한다.
4. 정량적 판단 사례
현재 구조:
- 고객별 최근 주문 20건 조회: p95 1.8초
- 목표: p95 300ms 이하
- 호출: 피크 2,000회/분
- 주문 쓰기: 300건/초
- 조회 시 고객 테이블 조인으로 고객등급명을 표시
- 고객등급 변경: 하루 2만 건
후보 1: 주문에 현재 고객등급명 중복
- 예상 조회 p95: 220ms
- 고객등급 변경 시 과거 주문 수백만 건 갱신 가능
- 원천과 중복값 불일치 위험 매우 큼
후보 2: 주문에 주문시점 고객등급코드 저장 + 코드 테이블 조인
- 과거 사실 보존이라는 업무 의미가 명확
- 작은 코드 테이블 조인은 비용이 낮을 수 있음
- 현재 등급 표시가 필요하면 별도 조회
후보 3: 고객별 최근 주문 조회 전용 캐시/읽기 모델
- 허용 지연이 1분이라면 쓰기 모델의 중복 갱신을 줄일 수 있음
- 캐시 장애·재생성·일관성 정책 필요
결론은 “가장 빠른 구조”가 아니라 업무 의미와 허용 지연, DML 비용까지 포함한 총비용으로 선택한다.
5. 정합성 통제 설계
| 통제 항목 | 질문 | 예시 |
|---|---|---|
| 원천 | 최종 진실은 어느 데이터인가? | 주문라인이 주문총액의 원천 |
| 갱신 책임 | 누가 언제 중복값을 갱신하는가? | 주문 서비스 트랜잭션 |
| 동기/비동기 | 지연을 얼마나 허용하는가? | 요약은 최대 5분 지연 |
| 순서·멱등성 | 재시도·중복 이벤트를 견디는가? | 이벤트ID별 1회 집계 |
| 오류 탐지 | 불일치를 어떻게 찾는가? | 일별 상세합계-요약 대조 |
| 복구 | 잘못된 값을 어떻게 재생성하는가? | 기간별 전체 재집계 |
| 철회 | 반정규화를 제거할 조건은? | DML 비용이 목표 초과, 조회패턴 변화 |
6. 판단 흐름
병목과 목표를 측정
↓
정규 구조에서 SQL·인덱스·통계·처리주기 대안 검토
↓
후보별 읽기 이득 / DML·저장·정합성 비용 산정
↓
업무 원천·허용 지연·갱신 책임·복구 방법 정의
↓
대표·피크·장애 부하로 검증
↓
적용 후 모니터링 및 철회 기준 설정
7. 비교와 구분
| 구분 | 정규화 | 반정규화 | 단순 중복 오류 |
|---|---|---|---|
| 목적 | 종속 정리·이상 제거 | 측정된 성능·가용성 요구 해결 | 편의 또는 무계획 |
| 원천 | 각 사실의 한 위치 | 원천과 복제 위치 명시 | 원천 불명확 |
| 정합성 | 구조로 이상 감소 | 별도 동기화 필요 | 불일치 방치 |
| 근거 | 함수 종속 | 성능·부하·운영 수치 | “조인이 싫다” |
| 재검증 | 업무 규칙 변경 | 부하·비용·지연 변화 | 기준 없음 |
시험 판단 포인트
- 반정규화는 정규화된 모델과 측정된 성능 문제를 전제로 한다.
- 조인 존재 자체는 반정규화 근거가 아니다.
- 읽기 성능 향상만 보지 말고 DML·저장공간·동기화·복구 비용을 함께 본다.
- 중복 컬럼의 값이 현재값인지 사건 시점 스냅샷인지 업무 의미를 구분한다.
- 적용 후에도 효과와 불일치율을 측정하고 필요하면 철회해야 한다.
자주 틀리는 부분
- 예상 성능만으로 적용하고 기준선·부하 테스트를 남기지 않는다.
- 트리거나 애플리케이션 코드가 있으니 정합성이 자동 보장된다고 본다.
- 비동기 요약의 지연 허용치와 늦은 데이터 재처리를 정의하지 않는다.
- 모든 조회를 한 테이블에서 끝내려 행 폭과 DML 비용을 과도하게 키운다.
- 업무 스냅샷과 현재값 복제를 구분하지 않아 갱신 정책이 모순된다.
개념 확인 문제
문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.
01객관식 반정규화 적용의 가장 적절한 선행 조건은? A. 테이블 수가 많다. B. 조인이 한 번 이상 있다. C. 정규 구조에서 측정된 병목과 목표가 있고 다른 대안·정합성 비용을 비교했다. D. 개발자가 단일 SQL을 선호한다.
읽기·쓰기 우선순위와 실제 피크 부하를 재확인한다.
02객관식 상세 주문라인 합계를 주문총액 컬럼에 저장할 때 가장 중요한 통제는? A. 주문총액 컬럼명을 짧게 한다. B. 원천·산출식·갱신 트랜잭션·재계산·불일치 검증을 정의한다. C. 총액을 문자열로 저장한다. D. 주문라인 FK를 제거한다.
동기 중복 갱신을 비동기화할 수 있는지와 허용 지연을 검토한다.
03참·거짓 “반정규화로 조회가 빨라졌다면 DML 비용이나 정합성 오류율은 더 이상 측정할 필요가 없다.”
인덱스·SQL·캐시·조회 전용 모델 등 대안을 비교한다.
04수치 판단 반정규화 전 p95 조회는 1,200ms, 후에는 250ms다. 그러나 쓰기 처리량은 1,000TPS에서 620TPS로 감소했고 목표 쓰기 처리량은 800TPS다. 이 결과만으로 적용을 승인할 수 있는지 판단하시오.
정합성 오류와 장애 복구 시간을 함께 측정한다.
05설계 문제 월별 고객매출 요약 테이블을 도입하려 한다. 최소한 정의해야 할 원천·키·갱신·지연·검증·복구 항목을 작성하시오.
모범 답안
- 원천: 확정된 주문/결제 상세 중 어느 데이터를 매출 원천으로 삼는지
- 키:
(기준년월, 고객번호, 통화코드 등)업무 집계 차원을 반영 - 집계 규칙: 매출·취소·환불·세금·환율·반올림의 포함 기준
- 갱신 방식: 실시간 이벤트, 주기 배치 또는 혼합 방식
- 허용 지연: 예를 들어 원천 확정 후 최대 10분
- 멱등성: 동일 주문 이벤트 재처리 시 중복 집계 방지
- 늦은 데이터: 과거 월 정정·환불 시 재집계 범위
- 검증: 월별 상세 합계와 요약 합계 대조, 차이 임계치
- 복구: 특정 월·고객 또는 전체 월을 원천에서 재생성
- 완료 상태: 집계 기준시각과 배치 성공 여부
- 철회/재평가: 조회 감소, 지연 초과, DML 비용 증가 시 기준
요약값만 정의하고 원천과 재생성 방법이 없으면 운영 가능한 반정규화가 아니다.