SCD(slowly chainging dimesion)

Dae-Hwa Jeong·2026년 2월 7일

디멘젼/팩트 구성에 대한 방법론 (SCD)

요구되는 분석 관점에 따라 보관 방식을 선택한다.
(현재값만 유지할지, 시점 이력을 보존할지, 제한된 이력만 남길지)

각각의 Type으로 구분.

Type4는 문헌에 따라 정의가 혼용되기도 한다. 여기서는 mini-dimension(킴볼 정의) 를 Type4로 두고, “현재+히스토리 테이블 분리” 패턴은 참고로 별도 표기함.


테이블 예시 시나리오

  • 고객 C001의 세그먼트가 변경됨

    • 2025-01-01 ~ 2025-02-14: SMB
    • 2025-02-15 ~: ENT
  • Fact(매출) 2건

    • 2025-02-10 매출 100 (변경 전)
    • 2025-03-01 매출 200 (변경 후)

Type1 (Overwrite)

단순히 덮어쓰는(overwrite) 방식. 이력 유지는 되지 않는다.

이러면 업데이트 될때마다 속성 기준으로 미리 만들어 둔 집계(aggregate), 물리화 결과(MV/큐브)는 재계산이 필요할 수 있음.

과거의 데이터도 완전히 바뀌어야 하는 경우에 사용.
예를 들어 항상 최신 속성으로만 봐야 하는 경우(회원 정보에 문제나 오타가 있어 정정을 해야 하는경우)

테이블 예시

dim_customer (Type1)

customer_idsegment
C001SMB

변경 후(2025-02-15)

customer_idsegment
C001ENT

팩트는 C001 만 참조하면 되니 변함이 없음. 즉 기록에 대한 참조가 사라진다.


Type2

변경 발생 시 새로운 행을 추가하고 대체키(surrogate key)를 부여한다.

유효한 시작일/종료일과 current 플래그를 두는 구성이 흔함.

하나의 테이블로 이력과 시점 추적이 가능(정석적이라고 함)

대신 변경이 잦을 경우 로우가 계속해서 증가하고, ETL 단계에서 매핑이 필요함.

Fact 적재 시점에 해당 일자/시점에 유효한 차원 버전(SK)을 찾아서 FK로 저장

테이블 예시

dim_customer (Type2)

customer_skcustomer_idsegmentvalid_fromvalid_tois_current
101C001SMB2025-01-012025-02-14N
102C001ENT2025-02-159999-12-31Y

fact_sales

sales_dtamountcustomer_sk
2025-02-10100101
2025-03-01200102

이미 쌓인 과거 Fact는 일반적으로 업데이트하지 않고, 과거 SK를 계속 참조하는 형태


Type3

현재 값과 다른 컬럼에 이전값과 현재 값을 동시에 저장하는 것. 현재 값은 업데이트.

이걸 대체 현실(alternate reality)로 표현하기도 하며, 상대적으로 드물게 사용.

바로 직전 값과 현재 값만 비교해도 충분한 경우에 사용.
데이터가 커지진 않지만 직전 이력 이전의 이력은 동일하게 소실됨.

개인적으로 e-value가 필요한 실시간 마트성 데이터가 이런 류가 아닌가 싶음

테이블 예시

dim_customer (Type3)

customer_idsegment_currentsegment_prev
C001SMB(null)

변경 후(2025-02-15)

customer_idsegment_currentsegment_prev
C001ENTSMB

Type4 (Mini-Dimension)

변경이 잦은 속성 그룹은 mini-dimension으로 분리하는 방식.

차원폭증(rapidly changing monster dimension) 문제를 완화한다고 알려져 있음.

둘의 차이점은(여기서는 “mini-dimension” vs “history table 패턴”을 구분해서 적음)

  • mini-dimension의 경우

    • 베이스 디멘젼은 자주 변하지 않는 속성으로 채우고, 자주 변하는 속성 그룹을 미니 디멘젼으로 만든다.
    • 데이터 변경 시 Fact에 (base FK + mini FK) 를 함께 저장하는 형태가 흔함(팩트를 “나눈다”기보단 FK가 2개로 늘어나는 느낌)
    • 미니 디멘젼은 “고객 개별 이력”이라기보단 속성 조합(프로파일) 카탈로그 성격이 강함
  • 히스토리 테이블 패턴(참고)

    • “현재 테이블 + 이력 테이블”로 분리해서 운영하는 방식
    • Fact 시점과 valid 기간을 맞추는 range join이 필요한 경우가 많음

조인 복잡도가 상승하고 etl도 복잡해진다(당연하지만)

나는 결제 내역과 결과를 분리할때 이런 방식을 사용했었다.

mini-dimension 테이블 예시

dim_customer_base

customer_skcustomer_idname
501C001Alice

dim_customer_profile (mini-dimension)

profile_sksegment
9001SMB
9002ENT

fact_sales

sales_dtamountcustomer_skprofile_sk
2025-02-101005019001
2025-03-012005019002

(참고) history table 패턴 테이블 예시

dim_customer_current

customer_idsegment_current
C001ENT

dim_customer_history

customer_idsegmentvalid_fromvalid_to
C001SMB2025-01-012025-02-14
C001ENT2025-02-159999-12-31

나머지 타입 (Hybrid)

아래 5/6/7은 “과거 이력을 보존”하면서도 “현재 속성 기준으로 과거 사실을 재분류해서 보고 싶다” 요구를 지원하기 위한 하이브리드로 알려져 있음.

Type5 (Type4 + Type1 Outrigger)

Type 4 + 1

mini-dimension을 쓰되, base dimension에 현재 mini-dimension 키를 Type1처럼 덮어써서 현재 속성 접근을 단순화하는 방식.

dim_customer_base (Type5 느낌)

customer_skcustomer_idnamecurrent_profile_sk
501C001Alice9002

Type6 (Type2 + Current Type1 Overlay)

Type 2 + 1 (+3로도 설명됨)

행 추가는 Type2처럼 하되, 차원에 현재값 컬럼(Type1) 을 두고, 그 현재값 컬럼은 동일 customer_id의 모든 버전 행에 대해 덮어쓴다.

과거 행에는 history 속성 제공하고 현재의 값도 같이 제공한다.

과거의 값과 현재값 대조/분석이 필요한 경우에 좋을듯 하다 → 추측임

dim_customer (Type6 예시)

customer_skcustomer_idsegment_histsegment_current
101C001SMBENT
102C001ENTENT

Type7 (Dual Type 1 and Type 2 Perspectives)

팩트가 두 개의 FK를 가진다.

  • Type2 버전으로 가는 surrogate key(당시 기준)
  • 현재 행으로 가는 durable/natural key(현재 기준)

타입 6에서 디멘젼의 업데이트 부담을 덜 수 있다(차원 과거행에 current 컬럼을 덮어쓰는 부담 회피).

(참조하는 팩트 테이블에 적재 시점에 두 키를 함께 저장하는 것)

fact_sales (Type7 예시)

sales_dtamountcustomer_skcustomer_id
2025-02-10100101C001
2025-03-01200102C001

선택기준?

  • 이력 필요 없음(항상 최신만) → Type1
  • 시점 이력 필요(정산/감사/시점 분석) → Type2
  • 현재 vs 직전만 필요 → Type3
  • 일부 속성군이 너무 자주 변해 Type2 폭증 → Type4(mini-dimension)
  • “as-was + as-is” 둘 다 편하게 → Type6/7
profile
대화로그

0개의 댓글