には model 以外に seeds ( ロード) と snapshots (履歴保存) という機能があります。それぞれ用途が明確で、知っておくと「model 化するべきか seed か」「変更履歴をどう残すか」の判断が楽になります。
seeds:CSV を にロード
code,name_ja,name_en,regionJP,日本,Japan,asiaUS,アメリカ合衆国,United States,north_americaGB,イギリス,United Kingdom,europeDE,ドイツ,Germany,europedbt seed # 全 seed を再ロード (デフォルト truncate+insert)dbt seed --select country_codes # 特定だけdbt seed --full-refresh # スキーマ含めて作り直しseeds: analytics: country_codes: +column_types: code: varchar(2) name_ja: varchar(100) name_en: varchar(100) region: varchar(50) industry_codes: +schema: reference # 別スキーマに分離seed は数千行までが現実解。10 万行を超えると `dbt seed` が遅くなり、 でも diff が読めない。大規模マスタは で取り込んで通常 model にすべき。
seed が向くケース
- 国コード・通貨マスタ: 数百行、めったに変わらない
- 業界コードのマッピング: NACE / GICS 等の固定マスタ
- 祝日カレンダー: 数年分の固定リスト
- 勘定科目マスタ: 中小企業なら数十〜数百行
- 設定値: しきい値、許可フラグ等の小規模ルックアップ
snapshots:SCD Type 2 を 1 設定で
SCD Type 2 = 「過去の状態を行として残しつつ、現在の状態も識別できる」スキーマ設計。dbt の snapshot はこれを 1 設定で実現します。
{% snapshot customers_snapshot %}
{{ config( target_schema='snapshots', unique_key='customer_id', strategy='check', -- 'check' or 'timestamp' check_cols=['email', 'phone', 'tier', 'address'], invalidate_hard_deletes=True ) }}
SELECT * FROM {{ source('app', 'customers') }}
{% endsnapshot %}dbt snapshot # 通常は 1 日 1 回 (cron で)# → snapshots.customers_snapshot に変化があった行が追記されるsnapshot が出力するカラム
| カラム | 意味 |
|---|---|
| `dbt_scd_id` | snapshot 行の一意 ID |
| `dbt_updated_at` | この行が記録された時刻 |
| `dbt_valid_from` | この状態が有効になった時刻 |
| `dbt_valid_to` | この状態が終わった時刻 (現在も有効なら NULL) |
| 元テーブルの全カラム | そのまま |
-- ある時点での顧客状態を取得SELECT *FROM {{ ref('customers_snapshot') }}WHERE customer_id = 'C001' AND '2027-06-01 00:00:00' BETWEEN dbt_valid_from AND COALESCE(dbt_valid_to, CURRENT_TIMESTAMP());
-- 顧客プラン変更の履歴SELECT customer_id, tier, dbt_valid_from, dbt_valid_toFROM {{ ref('customers_snapshot') }}WHERE customer_id = 'C001'ORDER BY dbt_valid_from;戦略の選択:check vs timestamp
| 戦略 | 判定方法 | 向く場面 |
|---|---|---|
| timestamp | ソースの updated_at が変わったら新行 | ソースに信頼できる updated_at がある場合 |
| check | 指定カラムの値が変わったら新行 | updated_at がない / 信頼できない場合 |
snapshot の落とし穴
ソーステーブルから行が 削除された場合、デフォルトでは検知されない。`invalidate_hard_deletes: True` を設定すると、消えた行に `dbt_valid_to` を入れて「終了」扱いにする。ハード削除がある業務テーブルには必須。
`dbt snapshot` を実行した瞬間の状態が記録される。1 時間に 1 回なら 1 時間内の変化は捨てられる。取りたい粒度に応じて頻度を決める (通常は 1 日 1 回 〜 1 時間 1 回)。
snapshot テーブルは 削除も full-refresh も基本しない(過去履歴が消える)。snapshot 戦略を変えるときは新 snapshot を立てるのが正解。
次の話
EP.11 では incremental model の差分更新パターンを深掘りする予定です(近日公開)。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。