본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

Dimensional Modeling — Fact 와 Dimension

~13 min · modeling, kimball, dimensional

Level 0구경꾼
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

모든 분석 팀이 공유하는 어휘

Kimball 의 dimensional model 은 30년째 분석 테이블의 표준 mental model 이야. 그 어휘 — fact 테이블, dimension 테이블, grain, conformed dimension — 는 모든 warehouse, 모든 dbt 프로젝트, 모든 BI 도구에 나와. 한 번 익혀 두면 평생, 어느 팀에 가든 대화가 바로 통해.

두 종류의 테이블

  • Fact 테이블엔 일어난 일이 담겨 — 주문, 페이지뷰, 결제, 센서 reading. Row 하나가 이벤트나 측정 하나야. Column 은 대부분 숫자 (measure) 에 dimension 테이블로 가는 foreign key.
  • Dimension 테이블엔 서술하는 맥락이 담겨 — 고객, 제품, store, 날짜. Row 하나가 이벤트가 아니라 사물 하나야. Column 은 대부분 속성 (이름, 나라, 카테고리, 색).

Grain — 제일 중요한 단어

Fact 테이블의 grain 은 row 하나가 뭘 나타내는지야. "주문당 한 row" 가 하나의 grain 이고, "주문 line item 당 한 row" 는 다른 grain 이고, "고객당, 일자당 한 row" 는 또 다른 grain 이야. Grain 을 틀리면 그 테이블 위에서 계산하는 모든 metric 이 미묘하게 어긋나 — row 가 엉뚱한 수준에서 합쳐지니까. 새 fact 테이블을 만들 때 제일 먼저 적는 건 grain 이야 — 한 문장으로, schema 맨 위에.

Conformed dimension

Conformed dimension 은 여러 fact 테이블이 같은 key 로 함께 쓰는 dimension 테이블이야. orders fact 테이블에도 그리고 support_tickets fact 테이블에도 join 되는 customers dimension 이 conformed 야. 여러 source 의 신호를 묶는 "customer-level" metric 을 — 리포트마다 짜깁기 로직을 새로 발명하지 않고 — 얻는 길이 이거야.

Code

SQL 의 작은 star schema — orders fact + customer/product/date dimension·sql
-- Fact: 주문 line item 당 한 row (grain)
CREATE TABLE fact_orders (
    order_id      TEXT NOT NULL,
    line_item_id  TEXT NOT NULL,
    customer_key  INTEGER NOT NULL REFERENCES dim_customers(customer_key),
    product_key   INTEGER NOT NULL REFERENCES dim_products(product_key),
    date_key      INTEGER NOT NULL REFERENCES dim_date(date_key),
    quantity      INTEGER NOT NULL,            -- measure
    amount_usd    NUMERIC(18, 2) NOT NULL,     -- measure
    discount_usd  NUMERIC(18, 2) DEFAULT 0,    -- measure
    PRIMARY KEY (order_id, line_item_id)
);

-- Dimension: 고객당 한 row (현재 상태, 이력은 SCD lesson 참조)
CREATE TABLE dim_customers (
    customer_key  INTEGER PRIMARY KEY,         -- surrogate key, join 위한 정수
    customer_id   TEXT NOT NULL UNIQUE,        -- source 의 자연 key
    name          TEXT NOT NULL,
    country       TEXT,
    tier          TEXT,                         -- gold/silver/bronze
    created_at    TIMESTAMP NOT NULL
);

-- Dimension: 제품당 한 row
CREATE TABLE dim_products (
    product_key   INTEGER PRIMARY KEY,
    sku           TEXT NOT NULL UNIQUE,
    name          TEXT NOT NULL,
    category      TEXT,
    list_price    NUMERIC(18, 2)
);

-- Dimension: 캘린더 날짜당 한 row — date dimension 은 친구
CREATE TABLE dim_date (
    date_key   INTEGER PRIMARY KEY,           -- 20260430
    full_date  DATE NOT NULL,
    year       INTEGER NOT NULL,
    quarter    INTEGER NOT NULL,
    month      INTEGER NOT NULL,
    day_of_week INTEGER NOT NULL,
    is_weekend BOOLEAN NOT NULL
);

External links

Exercise

본인 팀이 자주 묻는 분석 질문 하나 ("국가별 월별 매출", "기능별 DAU", "tier 별 NPS") 를 골라 fact 테이블과 conformed dimension 을 스케치해 봐. Fact 테이블 맨 위에 grain 을 한 문장으로 적어. 이 연습의 핵심은 schema 가 질문에서 흘러나온다는 감각이야 — 그 반대가 아니라.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.