【dbt】dbt ~ snapshot ~

◾️はじめに

 病院の待ち時間で、暇だったので
前から気になっていた「dbt snapshot」について調べていたら、
自分がイメージしている機能とは違っていた。

 また、結構知らないこと(例えば、SCD(Slowly Change Dimensions)など)
があったので、メモしておく
なお、Hello world的なことは、以下の関連記事を参照のこと

dbt CLI ~ dbt snapshot ~
https://dk521123.hatenablog.com/entry/2025/05/27/003532

目次

【1】dbt snapshot
 1)具体例
【2】用途
【3】スナップショットする際の種類
 1)タイムスタンプ戦略 (strategy: timestamp)
 2)チェック戦略 (strategy: check)
【4】ベストプラクティス
 1)タイムスタンプ戦略を使用する
 2)dbt_valid_to_currentを使用する
 3)ユニークキーは本当に一意か確認する
 4)別スキーマを使用する
 5)エフェメラル・モデルを使用する
【5】補足:SCD(Slowly Change Dimensions)
 1)SCD Type 1: overwrite
 2)SCD Type 2: add new row

【1】dbt snapshot

* 過去時点の状態の遷移を蓄積できるような仕組み
* Type-2 Slowly Changing Dimensions(SCD) の思想で実装
 => SCD に関する詳細は、
  後述「【4】補足:SCD(Slowly Change Dimensions)」を参照

メモ

* snapshot (スナップショット)と聞いて、
 バックアップ機能かと思ったが、全然違っていた、、、

1)具体例

って言ってもよく分からないと思うので、
以下の公式ドキュメントの具体例を見ていく

https://docs.getdbt.com/docs/build/snapshots

以下のような「更新前」と「更新後」のテーブルがあったとする

更新前

id status updated_at
1 pending 2024-01-01

更新後(status: pending-> shipped)

id status updated_at
1 shipped 2024-01-02
 上記の更新があった場合、snapshot機能により、
以下のような履歴テーブルを作成してくれる
 => これにより、Type-2 SCD「過去時点の状態の遷移を蓄積できるような仕組み」
  を実現してくれる

snapshot機能で作成された履歴テーブル

* id~updated_at: オリジナルテーブルのまま
* dbt_valid_from~ dbt_valid_to: そのデータの有効期限(FromとTo)
id status updated_at dbt_valid_from dbt_valid_to
1 pending 2024-01-01 2024-01-01 2024-01-02
1 shipped 2024-01-02 2024-01-02 null

【2】用途

* テーブルのあの時点のデータに戻りたいって時のために利用

【3】スナップショットする際の種類

* Type-2 Slowly Changing Dimensions(SCD) で実装する際に
 どう実装するかを選ぶ必要がある
 => その際に「strategy: timestamp | check」 で選ぶ

構文・抜粋

snapshots:
  - name: string
    config:
      strategy: timestamp | check

1)タイムスタンプ戦略 (strategy: timestamp)

* updated_at フィールドを使用して行が変更されたかどうかを判断
 => 使用するには、最終更新日時を表す列が必要
* dbt公式の推奨戦略

2)チェック戦略 (strategy: check)

* 指定されたカラムのリストを、現在の値と履歴の値で比較することで
 行が変更されたかどうかを判断
* 「1)タイムスタンプ戦略」ができなかった際に使用する戦略

【4】ベストプラクティス

* 以下の公式ドキュメントより抜粋

https://docs.getdbt.com/docs/build/snapshots#configuring-snapshots

1)タイムスタンプ戦略を使用する

* Use the timestamp strategy where possible
 => 可能な限りタイムスタンプ戦略を使用すること

2)dbt_valid_to_currentを使用する

* Use dbt_valid_to_current for easier date range queries
 => 日付範囲のクエリを簡単にするために、dbt_valid_to_currentを使用すること

3)ユニークキーは本当に一意か確認する

* Ensure your unique key is really unique
 => ユニークキーが本当に一意かどうか確認すること

4)別スキーマを使用する

* Use a schema that is separate to your models' schema
 => モデルのスキーマとは別スキーマを使用すること

5)エフェメラル・モデルを使用する

* Use ephemeral model to clean or transform data before snapshotting
 => スナップショット前にデータをクリーニングまたは変換するために
  エフェメラル・モデルを使用すること

cf. ephemeral(エフェメラル) = 一時的な,つかの間の

【5】補足:SCD(Slowly Change Dimensions)

* データ変更履歴の管理手法
 => 詳細は以下のサイトなどを参照

https://zenn.dev/pei0804/articles/slowly-changing-dimensions
https://www.cdata.com/jp/blog/cdatasync-scd
https://data.gunosy.io/entry/dbt_snapshot_and_scd

* Type0からType7まで8種類ある
 => dbt snapshot は、SCD Type2 Dimensionに従っている
Type Outline Memo
Type 0 retain original オリジナルのまま、何もしない
Type 1 overwrite 上書きで変化に対応する
Type 2 add new row 新規レコードの追加で変化に対応する
Type 3 add new attribute カラムの追加で変化に対応する
Type 4 add history table 履歴テーブルに切り出して変化に対応する
Type 5 -
Type 6 combined approach
Type 7 Hybrid - Both surrogate and natural key

1)SCD Type 1: overwrite

* 変更履歴を保持せずに変更を反映

2)SCD Type 2: add new row

* 変更履歴を保持して変更を反映
 => 履歴データをすべて保持していくことができるようにするもので、
  変更情報を追加していく

参考文献

https://tech.timee.co.jp/entry/2024/06/11/151948
https://qiita.com/Ayumu-y/items/af48189c8168c7030707
https://zenn.dev/foursue/books/31456a86de5bb4/viewer/12d263

関連記事

dbt ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/06/30/000000
dbt ~ 環境設定編 ~
https://dk521123.hatenablog.com/entry/2023/12/16/152147
dbt ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/05/30/151003
dbt CLI ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2024/07/21/234811
dbt CLI ~ dbt snapshot ~
https://dk521123.hatenablog.com/entry/2025/05/27/003532