스타 스키마와 차원 모델링 기초
50 Data Modeling Interview Questions for DEs (2026 Guide) — DataVidhya blog Star Schema & Dimensional Modeling, Q11-14, 17-18 (pp.4-7) + SQL doc Q30
이 모듈을 다 읽으면
- 스타 스키마의 구조와 웨어하우스에서 기본값으로 선택되는 이유를 설명할 수 있다
- 팩트 테이블과 차원 테이블의 역할 차이를 예시로 구분할 수 있다
- 그레인(grain)이 왜 차원 모델링에서 가장 중요한 결정인지 설명할 수 있다
- 트랜잭션/주기적 스냅샷/누적 스냅샷 팩트 테이블의 차이와 각각의 용도를 설명할 수 있다
스타 스키마의 구조, 팩트/차원 테이블의 역할, 그레인 결정의 중요성, 세 가지 팩트 테이블 유형, 디제너릿 차원, 날짜 차원까지 차원 모델링의 핵심 기초를 다룬다.
스타 스키마 — 웨어하우스의 기본값
스타 스키마는 중앙의 팩트 테이블(fact table)이 여러 차원 테이블(dimension table)과 외래 키로 연결되는 차원 모델링 패턴이다. 다이어그램이 별(star) 모양처럼 보여서 이런 이름이 붙었다. 팩트 테이블에서 어떤 차원 테이블로든 보통 한 번의 JOIN(one hop)만 필요하고 BI 도구가 소비하기 쉬워서, 분석용 웨어하우스의 기본 선택지다. 특별히 다른 구조를 써야 할 강한 이유가 없다면 스타 스키마로 시작하는 것이 원칙이다.
핵심 포인트
- 스타 스키마는 팩트 테이블 하나가 여러 차원 테이블과 직접 연결되는 구조로, JOIN 횟수를 최소화한다.
- 특별한 이유가 없다면 웨어하우스 설계의 기본값은 스타 스키마다.
팩트 테이블 vs 차원 테이블, 그리고 그레인
팩트 테이블은 order_amount, click_count, shipment_weight처럼 측정 가능한 이벤트나 거래를 저장한다. 차원 테이블은 customer_name, product_category, store_location처럼 설명적 맥락을 저장한다. 흔한 실수는 '조인을 줄이기 쉬우니까'라는 이유로 설명적 속성을 팩트 테이블에 넣는 것인데, 이는 저장 공간을 부풀리고 갱신을 어렵게 만든다. 팩트는 숫자형이고 가산적(additive)이며, 차원은 분석의 '누가, 무엇을, 어디서, 언제, 왜'를 제공한다는 것이 핵심 구분이다.
그레인(grain)은 팩트 테이블의 각 행이 나타내는 세부 수준을 정의한다. 이커머스 팩트 테이블이라면 그레인이 '주문 라인 아이템당 하루 한 행'일 수도, '주문당 한 행'일 수도 있다. 그레인을 잘못 정하는 것은 차원 모델링에서 가장 치명적인 실수다 — 너무 성기게 잡으면 분석에 필요한 세부 정보를 잃고, 너무 세밀하게 잡으면 쿼리 성능이 나빠진다. 실무에서는 팩트 테이블을 설명하기 전에 반드시 그레인을 명시적으로 먼저 진술해야 한다: '이 테이블의 그레인은 거래 1건 × 제품 1개 × 매장 1곳 × 날짜 1일당 한 행이다.'
핵심 포인트
- 팩트 테이블은 숫자형·가산적 측정값을, 차원 테이블은 설명적 맥락(누가/무엇을/어디서/언제)을 담는다.
- 설명적 속성을 팩트 테이블에 넣는 것은 저장 공간을 부풀리고 갱신을 어렵게 만드는 흔한 실수다.
- 그레인은 팩트 테이블 한 행이 나타내는 세부 수준이며, 잘못 정하면 데이터 손실 또는 성능 저하로 이어지는 가장 치명적인 결정이다.
세 가지 팩트 테이블 유형, 디제너릿 차원과 날짜 차원
트랜잭션 팩트(transaction fact)는 개별 이벤트를 하나씩 기록한다(판매 1건당 한 행). 주기적 스냅샷 팩트(periodic snapshot fact)는 일정 간격마다 상태를 포착한다(계정별 월말마다 한 행). 누적 스냅샷 팩트(accumulating snapshot fact)는 시작과 끝이 명확한 프로세스를 추적하며, 주문이 접수·배송·배달 같은 단계를 거칠 때마다 같은 행을 갱신한다. '현재 재고 수준이 얼마인가' 같은 질문에는 트랜잭션 팩트가 아니라 주기적 스냅샷이 맞는 선택이다.
디제너릿 차원(degenerate dimension)은 별도의 차원 테이블 없이 팩트 테이블에 직접 존재하는 차원 키다. 주문번호(order_number)가 대표적인 예로, 팩트 행을 그룹핑하는 맥락은 제공하지만 별도 테이블에 넣을 만큼의 추가 속성이 없다.
날짜 차원(date dimension)은 거의 항상 가장 먼저 만드는 차원이다. 팩트 테이블에 원시 날짜를 저장하고 쿼리 시점마다 파싱하는 대신, fiscal_quarter, is_holiday, day_of_week, week_number 같은 속성을 미리 계산해 둔다. 보통 10~20년 치를 다루며 하루에 한 행이므로 약 3,650~7,300행 정도로 메모리에 전부 올라갈 만큼 작다.
핵심 포인트
- 트랜잭션 팩트는 이벤트 단위, 주기적 스냅샷 팩트는 정기적 상태, 누적 스냅샷 팩트는 시작~끝이 있는 프로세스를 추적한다.
- 디제너릿 차원은 별도 테이블 없이 팩트 테이블에 직접 존재하는 차원 키(예: 주문번호)다.
- 날짜 차원은 재무 분기, 공휴일 여부 등을 미리 계산해 둔, 보통 수천 행 규모의 작은 테이블이다.