상위: dbt
요약
dbt Snapshot은 변경 가능한(mutable) 소스 테이블의 변경 이력을 추적하는 기능이다. SCD Type 2(Slowly Changing Dimension)를 구현하여, 특정 시점의 데이터 상태를 조회할 수 있다.
왜 필요한가
소스 시스템의 테이블은 UPDATE로 기존 값을 덮어쓴다. 예를 들어 주문 상태가 placed → shipped → completed로 변경되면, 소스에는 최종 상태만 남는다.
Snapshot은 변경 전 값을 보존하여 "이 주문이 언제 shipped 상태였는가?"를 추적할 수 있게 한다.
정의 방법
# snapshots/orders_snapshot.yml (dbt >= 1.9)
snapshots:
- name: orders_snapshot
relation: source('jaffle_shop', 'orders')
config:
schema: snapshots
unique_key: order_id
strategy: timestamp
updated_at: updated_at
또는 SQL 블록 방식 (레거시):
-- snapshots/orders_snapshot.sql
{% snapshot orders_snapshot %}
{{
config(
target_schema='snapshots',
unique_key='order_id',
strategy='timestamp',
updated_at='updated_at'
)
}}
SELECT * FROM {{ source('jaffle_shop', 'orders') }}
{% endsnapshot %}
전략 (Strategy)
timestamp 전략
strategy: timestamp
updated_at: updated_at
소스 테이블에 updated_at 같은 타임스탬프 컬럼이 있을 때 사용한다. 해당 값이 변경되면 새 행을 삽입한다. 가장 권장되는 전략이다.
check 전략
strategy: check
check_cols: ['status', 'amount']
# 또는 check_cols: 'all'
타임스탬프 컬럼이 없을 때 사용한다. 지정한 컬럼의 값이 변경되면 새 행을 삽입한다. check_cols: 'all'은 모든 컬럼을 비교하지만 성능이 떨어진다.
결과 테이블 구조
Snapshot 실행 후 생성되는 테이블에는 dbt가 자동으로 메타 컬럼을 추가한다:
| 컬럼 | 설명 |
|---|---|
dbt_scd_id | 각 행의 고유 ID |
dbt_updated_at | 변경이 감지된 시점 |
dbt_valid_from | 이 행이 유효한 시작 시점 |
dbt_valid_to | 이 행이 유효한 종료 시점 (NULL = 현재 유효) |
예시 데이터
order_id | status | dbt_valid_from | dbt_valid_to
---------|-----------|--------------------|-----------------
1001 | placed | 2026-01-01 10:00 | 2026-01-03 14:00
1001 | shipped | 2026-01-03 14:00 | 2026-01-05 09:00
1001 | completed | 2026-01-05 09:00 | NULL
dbt_valid_to가 NULL인 행이 현재 상태이다.
실행
dbt snapshot # 모든 스냅샷 실행
dbt build # run + test + snapshot 통합
스냅샷은 주기적으로 실행해야 한다. 실행 간격 사이의 변경은 캡처되지 않는다. 예를 들어 하루 1회 실행하면, 하루 안에 placed → shipped → completed로 바뀌어도 최종 상태만 캡처된다.
관련 개념
- Models: 스냅샷 테이블을 모델에서
ref()로 참조할 수 있다 - Sources & Seeds: 스냅샷의 입력은 보통 Source이다