◾️はじめに
病院の待ち時間で、暇だったので 前から気になっていた「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