はじめに
先日 dbt Analytics Engineering Certification Exam を受験し、不合格となりました。
その反省を生かし、自分に足りなかった部分を復讐し、再受験に臨みます。
前回の記事で反省点をまとめたのでそれをもとに復習していく
基本ドキュメントに書いてあることしか書かないのだが、自分の言葉で書くことにより、知識の定着をねらう。
今回のテーマは「Materialization」
反省点のおさらい
試験では以下の内容について問う問題が結構あったように思うが、自身を持って答えられなかった。
- table, view, ephemeral, incremental model の特徴や使い分け、メリットデメリット
- increamental model におけるstrategyの種類と用途、メリットデメリット
- microbatchとか
- lookbackとか?
本題
Materialization の概要
一応概要からおさらいする。
Materialization とは 「dbtモデルを永続化するための戦略」とドキュメントに記載されている。
モデルとして記載したSQLの結果がデータウェアハウスに反映されるわけだが、その時にテーブルとして保存するのか、ビューにしてテーブルとしての実態は持たせないのか といったことを設定することができる。
その設定によりSQLクエリのパーフォーマンスだったり、ストレージの消費量が変わってくるので、適切なものを選ぼう というもの。
Materialization のタイプ
以下の5つから選ぶことができる。これをうまく使い分けるのがミソ。
- table
- view
- incremental
- ephemeral
- materialized view
設定方法
以下の3つ方法がある
- プロジェクトファイル(dbt_project.yml)
- モデルファイル(model/モデル名.sql)
- プロパティファイル(model/property.yml)
詳細はドキュメントを参照(反省ポイントではないため)
各タイプについて
ドキュメントを真面目に読んで理解して、自分で訳すのに疲れたのでClaudeに翻訳してもらった
View
view マテリアライゼーションを使うと、モデルは実行のたびに CREATE VIEW AS 文によってビューとして再構築される
メリット:
- 追加のデータ保存が不要
- 常に最新のレコードが反映される
デメリット:
- 大きな変換を行うビューや、他のビューの上に積み重なったビューはクエリが遅くなる
アドバイス:
- まずはモデルにビューを使い始め、パフォーマンスの問題に気づいてから別のマテリアライゼーションに切り替える
- ビューは、列のリネームやキャストのような大きな変換を行わないモデルに最適
Table
table マテリアライゼーションを使うと、モデルは実行のたびに CREATE TABLE AS 文によってテーブルとして再構築されます。
メリット:
- クエリが高速
デメリット:
- 特に複雑な変換の場合、再構築に時間がかかることがある
- ソースデータの新しいレコードは自動的にテーブルに追加されない
アドバイス:
- BIツールからクエリされるモデルにはテーブルマテリアライゼーションを使い、エンドユーザーの体験を向上させるのがよい
- 多くのダウンストリームモデルから使われる、処理の重い変換にも使った方がよい
Incremental(インクリメンタル)
インクリメンタルモデルを使うと、dbt は前回の実行以降に変更されたレコードだけをテーブルに insert または update できる
メリット:
- 新しいレコードだけを変換することで、ビルド時間を大幅に短縮できる
デメリット:
- インクリメンタルモデルは追加の設定が必要で、dbt の上級者向け
アドバイス:
- インクリメンタルモデルはイベント系データに最適
- dbt の実行が遅くなってきたときに使うことを検討する(最初からインクリメンタルモデルを使いうべきではない)
Ephemeral(エフェメラル)
エフェメラルモデルはデータベースに直接作成されない。代わりに、dbt はエフェメラルモデルのコードを共通テーブル式(CTE)として依存モデルに展開する。この CTE の識別子はモデルエイリアスで制御できるが、dbt は常にモデル識別子の先頭に dbt__cte を付加する。
メリット:
- 再利用可能なロジックを記述できる
- エフェメラルモデルはデータウェアハウス内の散らかりを減らし、クリーンに保つのに役立つ(カスタムスキーマを使ってモデルを複数のスキーマに分割することもあわせて検討)
デメリット:
- このモデルから直接 SELECT することはできない
- 操作(例:dbt run-operation で呼び出されるマクロ)はエフェメラルノードを ref() できない
- エフェメラルマテリアライゼーションを使いすぎると、クエリのデバッグが難しくなる
- エフェメラルマテリアライゼーションはモデルコントラクトをサポートしていない
アドバイス:
- エフェメラルマテリアライゼーションは以下の場合に使うのがよさげ
- DAG の早い段階にある、非常に軽量な変換
- 1〜2 個のダウンストリームモデルからしか使われない
- 直接クエリする必要がない
Materialized View(マテリアライズドビュー)
materialized_view マテリアライゼーションを使うと、ターゲットデータベースでマテリアライズドビューの作成と管理が行える。マテリアライズドビューはビューとテーブルを組み合わせたもので、インクリメンタルモデルと似たユースケースに対応する
メリット:
- マテリアライズドビューはテーブルのクエリパフォーマンスとビューのデータ鮮度を兼ね備えている
- インクリメンタルマテリアライゼーションと同様に動作するが、通常はデータベースによって定期的に自動リフレッシュされるため、インクリメンタルマテリアライゼーションのように dbt による定期バッチリフレッシュが不要
- マテリアライズドビューへの dbt run はビューと同様、コードのデプロイに相当する
デメリット:
- マテリアライズドビューはより複雑なデータベースオブジェクトであるため、データベースプラットフォームによって利用可能な設定オプションが少ない傾向がある
- すべてのデータベースプラットフォームでマテリアライズドビューがサポートされているわけではない
アドバイス:
- インクリメンタルモデルで十分だが、インクリメンタルロジックとリフレッシュをデータプラットフォームに任せたい場合は、マテリアライズドビューを検討する
深掘り(エフェメラルとマテリアライズドビュー、Python materializations)
エフェメラルとマテリアライズドビューの使い所がいまいちピンとこなかったので少し考えつつ、Claudeに聞きつつ自分なりに考察した
Python materializationsなるものは認識してなかったのでこれを機に見てみる
エフェメラル
-
一番の特徴
- データベース内にオブジェクトが作成されないこと
-
それってなにがいいんだっけ?ストレージ節約ならビューでよくね?
- モデルつくっていくうちに中間テーブルいっぱいできちゃってこちゃごちゃしてきちゃった場合、エフェメラルにすればデータベース内がスッキリする
- ビューの場合もデータベース内のオブジェクトとしては存在するからたくさんモデルがある場合は見づらくなる可能性がある(フォルダ内にファイルめっちゃあって整理しないと一覧性に欠けるなーと感じる現象と同じという理解)
-
デメリットにあった「使いすぎると、クエリのデバッグが難しくなる」ってどういうこと?
- 複数のエフェメラルモデルを中間層として経由するモデルがあった場合、エフェメラル部分が全部まとめて実行されるため、どこでエラーが起きたかわかりにくいということ
例えばこんな感じ
-- 実際に実行されるSQL(dbtが自動生成) WITH __dbt__cte__model_a AS (SELECT ...), __dbt__cte__model_b AS (SELECT ... FROM __dbt__cte__model_a), __dbt__cte__model_c AS (SELECT ... FROM __dbt__cte__model_b) SELECT * FROM __dbt__cte__model_c
マテリアライズドビュー
- 結局こいつはなんなの?
- 一言でいうと、ビューとテーブルとインクリメンタルのいいとこどり
- クエリが速い(テーブルのメリット)
- 毎回最新をとってきてくれる(ビューのメリット)
- 最新をとってきたときに差分だけ更新される(インクリメンタルのメリット)
- インクリメンタルとの違いは?
- 自動でリフレッシュしてれるところ
- 一言でいうと、ビューとテーブルとインクリメンタルのいいとこどり
Python materializations
- ドキュメントに書いてあったけどこれはなんだ?
- Python モデルがサポートするマテリアライゼーションのこと
- Python モデルでは以下をサポートする
- table
- incrimental
- view や ephemeral としてマテリアライズすることはできない
- テストやスナップショットといったモデル以外のリソースタイプには対応していない
まとめ
Materialization についてざっと復習した。
結構理解してないところがあったのでよい機会だった。
本当は increamental モデルの strategy についても書きたかったけどボリューム的にこのくらいがよいと思うので次回の記事に回します。