← 학습 카테고리

Learn

SQL

32개 모듈 · 현재 10번째

SQL 모듈 10/32 sql-learn-10

SCD와 이력 관리

50 Data Modeling Interview Questions for DEs (2026 Guide) — DataVidhya blog SCDs & History Tracking, Q21-28 (pp.7-10)

이 모듈을 다 읽으면

  • SCD Type 1/2/3/6의 차이와 각각을 선택하는 기준을 설명할 수 있다
  • 미니 차원이 대규모 SCD Type 2 문제를 어떻게 해결하는지 설명할 수 있다
  • 늦게 도착하는 차원(late-arriving dimension)을 처리하는 표준 패턴을 설명할 수 있다

Slowly Changing Dimension의 대표 유형(1/2/3/6), 실무에서 자주 등장하는 미니 차원과 브릿지+SCD 조합, 그리고 파이프라인 타이밍 이슈인 늦게 도착하는 차원 처리를 다룬다. SQL 구현 예시(MERGE 패턴)는 04번 모듈과 연결된다.

SCD란 무엇이고 왜 Type 1을 기본값으로 삼으면 안 되는가

Slowly Changing Dimension(SCD)은 시간에 따라 차원 테이블의 속성값이 바뀌는 상황을 다루는 설계 패턴이다. 고객이 뉴욕에서 시카고로 이사했을 때, 기존 주소를 덮어쓸지, 둘 다 보관할지, '이전' 컬럼을 둘지는 과거 값이 이력 분석에 필요한지에 달려 있다.

가장 흔한 실수는 '더 간단하다'는 이유로 모든 곳에 Type 1(덮어쓰기)을 기본값으로 쓰는 것이다. 그러다 6개월 후 비즈니스가 '이 고객이 그 주문을 넣었을 때 어느 지역에 있었는가'를 물으면, 그 데이터는 이미 사라지고 없다.

핵심 포인트

  • SCD는 차원 테이블 속성값이 시간에 따라 변할 때 이를 어떻게 다룰지 정하는 설계 패턴이다.
  • '더 간단하다'는 이유로 Type 1(덮어쓰기)을 기본값 삼는 것은 이후 과거 시점 조회가 필요할 때 데이터 유실로 이어지는 흔한 실수다.

SCD Type 1, 2, 3, 6

Type 1은 옛 값을 새 값으로 덮어써 이력을 남기지 않는다. Type 2는 변경마다 새 행을 만들고 effective_date, end_date, is_current 플래그로 버전을 추적한다 — 대부분의 웨어하우스에서 전체 이력을 보존하므로 기본값이지만, 주소를 5번 바꾼 고객은 5개 행을 만들어내므로 테이블 크기가 크게 늘어난다. Type 3은 previous_city처럼 '이전' 컬럼을 추가해 딱 한 번의 이전 값만 저장한다 — 조직 개편처럼 최근 변경 하나만 비교하면 되는 상황에 적합하지만, 추적할 속성이 5개면 컬럼이 10개 늘어나는 식으로 확장성이 떨어져 실무에서는 드물게 쓰인다.

Type 6(하이브리드, 1+2+3=6)은 세 방식을 결합한다. Type 2처럼 effective/end 날짜가 있는 행으로 전체 이력을 유지하면서, 같은 엔티티의 모든 행에 걸쳐 덮어써지는(Type 1) '현재' 컬럼을 추가하고, 선택적으로 '이전' 컬럼(Type 3)도 포함한다. 이렇게 하면 분석가는 `WHERE is_current = TRUE`로 최신 뷰를 조회하거나 날짜 범위로 JOIN해 이력 뷰를 조회할 수 있고, 모든 행에 있는 '현재' 컬럼 덕분에 나란히 비교하는 것도 쉬워진다.

핵심 포인트

  • Type 1은 덮어쓰기(이력 없음), Type 2는 새 행 추가(전체 이력, 행 수 증가), Type 3은 '이전' 컬럼 추가(제한적 이력, 확장성 낮음).
  • Type 2가 대부분의 웨어하우스에서 기본값이며, Type 3은 조직 개편처럼 최근 변경 하나만 필요할 때 드물게 쓰인다.
  • Type 6은 1+2+3을 결합한 하이브리드로, 최신 뷰와 이력 뷰를 동시에 지원한다.

미니 차원, 브릿지+SCD, 늦게 도착하는 차원

미니 차원(mini-dimension)은 빠르게 변하는 속성을 큰 차원에서 떼어내 별도의 작은 테이블로 만드는 기법이다. dim_customer가 1천만 행이고 loyalty_tier, credit_score_band 같은 컬럼이 매주 바뀐다면, 전체 차원에 SCD Type 2를 적용하는 것은 행 수를 폭발시킨다. 대신 그 휘발성 속성들만 담은 dim_customer_profile 미니 차원을 따로 만들고, 팩트 테이블이 dim_customer와 dim_customer_profile 양쪽을 모두 참조하게 한다.

09번 모듈에서 다룬 브릿지 테이블은 관계 자체가 시간에 따라 바뀔 때도 필요해진다 — 예를 들어 환자-담당의사 배정이 N:M이면서 분기마다 바뀐다면, 브릿지 테이블에 유효 시작/종료 날짜를 두어 언제 어떤 배정이 유효했는지 추적한다.

늦게 도착하는 차원(late-arriving dimension)은 팩트 레코드가 해당 차원 레코드보다 먼저 도착하는 경우다 — 고객 마스터 데이터가 로드되기 전에 거래가 먼저 기록되는 식이다. 표준적인 처리는 특수한 서로게이트 키와 기본값을 가진 자리표시(placeholder) 행을 차원 테이블에 먼저 넣고, 실제 데이터가 도착하면 갱신하는 것이다. SCD Type 2를 쓰는 경우, 늦게 도착한 데이터는 현재 날짜가 아니라 과거로 소급된(backdated) effective_date로 삽입해야 할 수도 있다.

핵심 포인트

  • 미니 차원은 빠르게 변하는 속성만 큰 차원에서 분리해 별도 테이블로 만들어 SCD Type 2의 행 폭발을 막는다.
  • 브릿지 테이블에도 유효 기간을 두면 관계 자체가 시간에 따라 바뀌는 경우를 추적할 수 있다.
  • 늦게 도착하는 차원은 자리표시 행을 먼저 넣고 나중에 갱신하며, 필요하면 effective_date를 과거로 소급한다.