← posts/b.log()

blog92@web:~$ cat posts/db-design-20-dimensional-modeling.md

DATABASE4 min read

DB 설계 A to Z 20강 — 차원 모델링

OLTP 모델과 분석 모델의 차이, Kimball 4단계와 스타 스키마, 팩트 테이블 세 유형, 준가산 측정값과 비율을 분자·분모로 저장하는 이유, 적합 차원과 버스 매트릭스를 다룬다.

지금까지의 모델은 정확한 쓰기를 위한 것이었습니다. 이번 강은 같은 데이터를 읽고 집계하기 위한 모델로 전환합니다.

1. OLTP 모델과 분석 모델의 차이

항목OLTP (정규화 모델)분석 (차원 모델)
목적정확한 쓰기, 무결성빠르고 쉬운 집계
구조수십~수백 테이블, 깊은 조인팩트 + 차원, 얕은 조인
쿼리소수 행 조회·변경대량 행 스캔·집계
중복최소화차원에서 허용
사용자애플리케이션분석가, BI 도구, 대시보드

KPI 대시보드가 OLTP 테이블을 직접 집계하면, 대시보드 쿼리가 운영 트랜잭션과 경합하고 쿼리가 복잡해집니다. 차원 모델은 이 문제를 구조로 해결합니다.

2. Kimball 4단계 설계

  1. 업무 선택: 주문 처리 실적
  2. 그레인(Grain) 선언: 팩트 한 행이 무엇을 의미하는가 → "담당자 1명이 1일 동안 1개 주문항목의 1개 처리단계에 투입한 기록"
  3. 차원 식별: 날짜, 담당자, 주문항목, 처리단계, 셀러
  4. 팩트(측정값) 식별: 투입 시수, 처리 인원, 처리 수량

그레인 선언이 가장 중요합니다. 그레인이 모호하면 같은 테이블에 일 단위와 월 단위 행이 섞여 이중 집계가 발생합니다.

3. 스타 스키마

text
                    [dim_date]
                        |
[dim_picker] —— [fact_fulfillment] —— [dim_order_item]
                        |
                   [dim_stage]    [dim_seller]
sql
CREATE TABLE dim_date (
    date_key     INT PRIMARY KEY,         -- 20260917
    full_date    DATE NOT NULL,
    year         SMALLINT NOT NULL,
    quarter      SMALLINT NOT NULL,
    month        SMALLINT NOT NULL,
    week_of_year SMALLINT NOT NULL,
    is_holiday   BOOLEAN NOT NULL,
    shift_calendar VARCHAR(10)            -- 물류센터 근무 달력
);
 
CREATE TABLE dim_order_item (
    item_sk        BIGINT PRIMARY KEY,    -- SCD Type 2 대리키
    item_id        BIGINT NOT NULL,       -- 원천 시스템 키 (자연키)
    item_name      VARCHAR(20) NOT NULL,
    product_type   VARCHAR(20) NOT NULL,  -- 유형명. 25강 product.product_type은 2자 코드다
    order_no       VARCHAR(10) NOT NULL,  -- 주문을 차원에 펼침 (반정규화)
    order_type     VARCHAR(20) NOT NULL,
    customer_grade VARCHAR(20) NOT NULL,
    valid_from     DATE NOT NULL,
    valid_to       DATE NOT NULL,
    is_current     BOOLEAN NOT NULL
);
 
CREATE TABLE fact_fulfillment (
    date_key     INT    NOT NULL REFERENCES dim_date,
    picker_sk    BIGINT NOT NULL REFERENCES dim_picker,
    item_sk      BIGINT NOT NULL REFERENCES dim_order_item,
    stage_sk     INT    NOT NULL REFERENCES dim_stage,
    seller_sk    INT    NOT NULL REFERENCES dim_seller,
    pick_order_no VARCHAR(20),            -- 퇴화 차원
    man_hours    NUMERIC(6,2) NOT NULL,
    work_qty     NUMERIC(10,2)
);

차원은 넓고 평평하게: 주문·주문유형·고객등급을 주문항목 차원에 펼쳐서 조인 한 번으로 모든 분류 기준을 쓸 수 있게 합니다.

sql
-- 주문유형별·월별 투입 시수
SELECT b.order_type, d.year, d.month, SUM(f.man_hours)
FROM fact_fulfillment f
JOIN dim_order_item b ON b.item_sk = f.item_sk
JOIN dim_date       d ON d.date_key = f.date_key
WHERE d.year = 2026
GROUP BY b.order_type, d.year, d.month;

4. 스노우플레이크 스키마

차원을 다시 정규화한 형태입니다 (dim_order_item → dim_order → dim_customer).

항목스타스노우플레이크
조인 수적음많음
차원 저장 공간큼작음
BI 도구 친화성높음낮음
차원 갱신여러 행한 행

차원 테이블은 팩트에 비해 매우 작으므로, 대부분 스타 스키마가 권장됩니다. 컬럼형 저장소에서는 반복값 압축 효율이 높아 공간 단점이 더 줄어듭니다.

5. 팩트 테이블의 세 유형

유형그레인예시특징
트랜잭션 팩트이벤트 1건처리 실적삽입만, 가장 상세
주기적 스냅샷기간 말 상태일말 주문 처리율, 월말 재고기간마다 전체 행 삽입
누적 스냅샷업무 1건의 생애주문항목 1개의 착수~완료 마일스톤여러 날짜 키, 행이 갱신됨

누적 스냅샷 예시

sql
CREATE TABLE fact_order_milestone (
    item_sk            BIGINT PRIMARY KEY,
    ordered_date_key   INT,    -- 주문 접수
    picked_date_key    INT,    -- 픽킹 완료
    packed_date_key    INT,    -- 포장 완료
    shipped_date_key   INT,    -- 출고 완료
    delivered_date_key INT,    -- 배송 완료
    ordered_to_delivered_days INT,
    total_man_hours    NUMERIC(10,2)
);

리드타임 분석(처리단계 간 소요일)은 이 형태가 가장 쉽습니다.

6. 측정값의 가산성

유형모든 차원으로 합산예시
가산 (Additive)가능투입 시수, 처리 수량
준가산 (Semi-additive)시간 차원으로는 불가재고 수량, 인원 현황 (월말 재고를 12개월 합하면 무의미)
비가산 (Non-additive)불가처리율, 단가, 비율

비율은 저장하지 말고 분자와 분모를 저장합니다.

sql
-- 나쁜 예: 처리단계별 처리율 평균의 평균 → 가중치 오류
-- 좋은 예
SELECT SUM(done_tasks)::numeric / NULLIF(SUM(total_tasks), 0) FROM fact_progress_snapshot ...;

7. 기타 핵심 개념

개념설명
적합 차원 (Conformed Dimension)여러 팩트가 공유하는 동일한 차원 → 실적과 검수를 같은 주문항목·날짜 기준으로 비교 가능
버스 매트릭스업무 × 차원 표로 적합 차원 계획
퇴화 차원속성 없이 키만 있는 차원 → 팩트에 직접 저장 (출고지시 번호)
팩트 없는 팩트측정값 없이 사건 발생만 기록 (교육 참석, 검수 대상 지정)
미상 차원 행-1 = 'Unknown' 행을 두어 팩트 FK의 NULL 방지

버스 매트릭스 예시

업무 \ 차원날짜주문항목처리단계담당자셀러검수자
처리 실적OOOOO
검수OOOOO
처리 스냅샷OOO
포장자재 출고OOO

8. 적재 파이프라인

text
원천 OLTP ──(CDC 또는 증분 추출)──▶ 스테이징
                                      │
                   차원 적재 (SCD 처리, 대리키 발급)
                                      │
                   팩트 적재 (자연키 → 대리키 조회)
                                      │
                   집계/스냅샷 생성 ──▶ 대시보드
  • 차원 먼저, 팩트 나중: 팩트가 참조할 대리키가 먼저 존재해야 합니다.
  • 늦게 도착한 차원(팩트는 왔는데 차원이 없음)은 미상 행이나 추정 행(inferred member)으로 처리합니다.
  • 레이크하우스 환경에서는 같은 설계가 Delta Lake/Iceberg 테이블 위에서 MERGE로 구현됩니다.

20강 정리

  1. 분석 모델은 팩트와 넓고 평평한 차원으로 구성하며, 그레인 선언이 가장 중요하다.
  2. 대부분 스타 스키마가 스노우플레이크보다 낫다.
  3. 트랜잭션·주기적 스냅샷·누적 스냅샷 세 팩트 유형을 목적에 맞게 쓴다.
  4. 비율은 분자·분모로 저장하고, 준가산 측정값의 시간 합산에 주의한다.
  5. 적합 차원과 버스 매트릭스로 여러 업무를 일관되게 분석한다.
COMMENTS (…)

댓글을 불러오는 중이에요.

NEW COMMENT0 / 1000
⌘↵ 전송

blog92@web:~$ cd ..