데이터베이스 반정규화(Denormalization) 전략
정규화를 의도적으로 깨뜨려 읽기 성능을 높이는 반정규화 기법과 데이터 무결성 관리 전략
Contents
정규화를 의도적으로 깨뜨려 읽기 성능을 높이는 대신, 데이터 무결성 관리 부담을 떠안는 설계 트레이드오프다.
반정규화란?
**반정규화(Denormalization)**는 정규화를 일부러 깨뜨리고 중복 데이터를 허용함으로써 읽기 성능을 개선하는 설계 기법이다.
정규화는 데이터 중복과 이상 현상을 최소화하지만, 비즈니스 요구에 따라 성능을 위해 트레이드오프가 필요할 때 반정규화를 적용한다.
반정규화의 필요성
성능 개선
-- 정규화된 구조: 3개 테이블 JOIN 필요
SELECT o.order_id, c.name, p.product_name
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id;
-- 반정규화 후: 단일 테이블 조회
SELECT order_id, customer_name, product_name
FROM orders_denormalized;개발 단순화
복잡한 다중 조인을 간소화하여 SQL과 애플리케이션 로직을 간결하게 만든다.
OLAP/BI 환경 최적화
OLAP(Online Analytical Processing)와 BI(Business Intelligence) 도구는 대량 데이터를 반복 조회한다.
분석 도구에서 여러 테이블을 반복 조인하는 비용을 줄여 분석 시간을 단축한다.
반정규화의 단점
| 단점 | 설명 |
|---|---|
| 데이터 불일치 | 중복 데이터 갱신 시 불일치 위험 |
| 쓰기 비용 증가 | INSERT/UPDATE/DELETE 시 더 많은 테이블 수정 |
| 구조 복잡도 | 어디서 중복을 유지하는지 파악 어려움 |
| 유지보수 어려움 | 시간이 지나면 설계 의도 파악 곤란 |
반정규화 기법
중복 속성 추가
-- 주문 테이블에 고객 이름 중복 저장
ALTER TABLE orders ADD COLUMN customer_name VARCHAR(100);
-- 장점: JOIN 없이 바로 조회
-- 단점: 고객 이름 변경 시 orders도 업데이트 필요집계 결과 저장
-- 일별 매출 집계 테이블
CREATE TABLE daily_sales_summary (
date DATE PRIMARY KEY,
total_sales DECIMAL(15, 2),
order_count INT,
avg_order_value DECIMAL(10, 2)
);
-- 실시간 집계 대신 미리 계산된 결과 조회Materialized View
-- PostgreSQL
CREATE MATERIALIZED VIEW order_summary AS
SELECT
date_trunc('day', order_date) as day,
SUM(amount) as total,
COUNT(*) as count
FROM orders
GROUP BY 1;
-- 주기적 갱신
REFRESH MATERIALIZED VIEW order_summary;MATERIALIZED VIEW는 집계 결과를 실제 테이블처럼 디스크에 저장해 둔다. 원본 orders가 바뀌어도 자동으로 반영되지 않으므로 REFRESH를 주기적으로 실행해 최신 상태로 다시 계산한다.
중복 테이블 복제
자주 쓰이는 참조 데이터를 여러 DB나 샤드에 복제하면 원격 조회가 줄어 네트워크 트래픽과 지연 시간이 함께 줄어든다. 다만 복제본마다 동기화 경로를 둬야 하므로 갱신 빈도가 낮은 데이터에 적합하다.
정규화 단계 해제
BCNF(Boyce-Codd Normal Form)에서 3NF(제3정규형)로 정규화 단계를 의도적으로 낮춰, 한 테이블에 더 많은 속성을 담아 조인 횟수를 줄인다. 대신 갱신 이상이 생길 수 있으므로 갱신이 드문 속성에만 적용한다.
적용 시 고려사항
접근 패턴 분석
- 읽기 비중 높음 (99% 읽기, 1% 쓰기): 반정규화 적합
- 쓰기 비중 높음 (50% 읽기, 50% 쓰기): 반정규화 신중히 검토
명확한 성능 목표
- 쿼리 응답 시간 목표 수치화
- 충분한 벤치마크 테스트 진행
- 무조건적인 반정규화 피하기
데이터 동기화 전략
| 방식 | 장점 | 단점 |
|---|---|---|
| 트리거 | 실시간 동기화 | DB 부하 증가 |
| 배치 작업 | DB 부하 분산 | 일시적 불일치 |
| 애플리케이션 로직 | 유연함 | 코드 복잡도 증가 |
반정규화 전 검토 사항
반정규화 결정 전에 먼저 고려해야 할 것들:
- 실행 계획(EXPLAIN) 분석
- 인덱스 최적화
- 캐싱 도입 (Redis, Memcached)
- 쿼리 튜닝
이 방법들로 충분하지 않을 때만 반정규화를 검토한다.
정리
| 환경 | 반정규화 권장도 |
|---|---|
| OLAP/BI/데이터 마트 | 높음 |
| 읽기 위주 웹 서비스 | 중간 |
| OLTP(Online Transaction Processing, 트랜잭션 중심) | 낮음 |
반정규화는 읽기 성능이 병목인 환경에서 효과가 크지만, 중복 데이터의 동기화 비용을 누가 언제 감당할지 먼저 정해야 한다. 트리거·배치·애플리케이션 로직 중 어느 경로로 동기화할지, 불일치가 허용되는 시간 범위가 얼마인지 측정한 뒤 도입한다.
읽기 비중과 동기화 비용을 측정하지 않은 채 적용하면 쓰기 경로만 무거워진다. 동기화 부담이 이득을 넘어서면 반정규화를 되돌리고 인덱스·캐싱으로 회귀하는 기준도 함께 정해 둔다.