dbtを深く使いこなす
「dbtの基本までは触ったけれど、incrementalで詰まっている」「テストが効いている気がしない」「Snowflakeコストが月末に跳ねた」「履歴管理ってどうやるの」という人向けの5ステップ。完走目安35〜40分。
テーブルが大きくなり、full-refreshが時間内に終わらなくなったときに使うのがincremental modelsです。「初回は全件、以降は差分だけ追記」が基本動作。unique_keyとis_incremental()の組み合わせで、Snowflake/BigQueryでは既定のmerge戦略により差分を反映します。
ハマりどころは4つ。遅延データで欠損(過去N日まで遡る窓を入れる)、unique_key忘れで重複、mergeターゲットが大きすぎる重さ(パーティション分割/insert_overwrite)、累積不整合(定期full-refresh)。on_schema_changeは「append_new_columns」など明示が安全です。
「unique_not_nullだけ書いて満足」が一番危ない状態です。本当に効くdbtテストは3層で組みます。generic(schema.ymlで宣言、unique/not_null/relationships/accepted_values)が骨格、singular(SQLファイルで業務ルール)が固有制約、dbt-expectationsが統計検査と表現力の補強。
severity(error/warn)とwarn_if/error_ifで深刻度を制御し、store_failures: trueで失敗行を専用テーブルに保存すると、原因調査が劇的に楽になります。「同じsingularが3回出てきたらgeneric化」が運用のリズム。
月末に跳ねるSnowflakeクレジットには、定型パターンがあります。(1) materialization選定ミス(大きなテーブルがtable)、(2) ウェアハウスサイズ過剰、(3) full-refreshの乱用、(4) auto_suspendが長い、(5) ジョブの並行衝突、(6) 使われていないGoldマートが毎晩構築。この6つを潰すと、コストは半分以下になることが多いです。
特に効くのは「dbtのquery_tag」でモデル別クレジット消費を可視化し、重いトップ10にmaterializationやウェアハウスの最適化を集中させること。auto_suspendはdbt用60秒、BI用300秒など用途で分けます。
「半年前の時点でこの顧客はどの住所だったか」を答えるには、SCD Type 2(履歴を残す設計)が要ります。dbtのsnapshot機能で、設定ファイル数十行で実装できます。timestamp戦略(updated_atベース)が基本、信頼できる更新日時がなければcheck戦略。
下流でファクトと結合するときは `dbt_valid_from <= ts AND (dbt_valid_to IS NULL OR dbt_valid_to > ts)` で時点JOINします。実行頻度が履歴の粒度を決めるので、業務要件で日次か時間ごとかを設計します。物理削除を履歴に反映したいなら invalidate_hard_deletes=True。
dbtを使い込むと、本体だけでは足りない場面が出てきます。dbt-osmosisは「上流のdescriptionを下流に自動継承」、dbt-checkpointはpre-commit hookで「主キー必須」「テスト必須」などのルールを強制。両者は補完関係で、CIで併用するのが定番です。
SQLMeshはdbtの「不便」を根本から解こうとする新興ツールで、Virtual Environments(本番データを複製せずdev環境)・状態管理・カラムレベルリネージが強み。新規プロジェクトの選択肢として現実的になりつつあります。dbt一強の時代から、複数選択肢の時代に。
学習パス完走、おめでとうございます
dbtの「基本の次」を一通り押さえました。データ基盤のコスト診断や、incremental設計の壁打ちは、初回相談(30分・無料)をご利用ください。
初回相談(30分・無料)について