dbt の Best practice guides におけるモデルのレイヤー分け
dbtdbt Labs がどのように dbt プロジェクトを構築しているかを記した Best practice guides がある。その中の How we structure our dbt projects には、フォルダの切り方やファイル名を考えるのに決断リソースを割かなくて良いように、するべきことやするべきでないこと、その理由が示されている。
├── models
│ ├── intermediate
│ │ └── finance
│ │ ├── _int_finance__models.yml
│ │ └── int_payments_pivoted_to_orders.sql
│ ├── marts
│ │ ├── finance
│ │ │ ├── _finance__models.yml
│ │ │ ├── orders.sql
│ │ │ └── payments.sql
│ │ └── marketing
│ │ ├── _marketing__models.yml
│ │ └── customers.sql
│ ├── staging
│ │ ├── jaffle_shop
│ │ │ ├── _jaffle_shop__docs.md
│ │ │ ├── _jaffle_shop__models.yml
│ │ │ ├── _jaffle_shop__sources.yml
│ │ │ ├── base
│ │ │ │ ├── base_jaffle_shop__customers.sql
│ │ │ │ └── base_jaffle_shop__deleted_customers.sql
│ │ │ ├── stg_jaffle_shop__customers.sql
│ │ │ └── stg_jaffle_shop__orders.sql
│ │ └── stripe
│ │ ├── _stripe__models.yml
│ │ ├── _stripe__sources.yml
│ │ └── stg_stripe__payments.sql
│ └── utilities
│ └── all_dates.sql
staging
名前の変更や、型やカテゴリ変換などをを行い、基本的に JOIN や集計などは行わない。常に最新のデータを参照するために view として materialize される。
ディレクトリは、データのロード方法や財務やマーケティングといったビジネスグループごとではなく、同様のプロパティを共有する傾向がある、システムの粒度で切る。
ファイル名は stg_[source]__[entity]s.sql のような、ツリーを見る事なくそのモデルがどこから来たかわかるものにする。
直接テーブルを参照することもできるが、sources.yml を source() で参照することでドキュメントに反映できる。このファイルおよび rename する model のベースは codegen で自動生成できる。
dbt の codegen で sources.yml や staging の model、schema.yml を自動生成する - sambaiz-net
sources:
- name: dbttest
tables:
- name: my_first_dbt_model
- name: my_second_dbt_model
# select * from {{ source('dbttest', 'my_first_dbt_model') }}
intermediate
staging のモデルをまとめたり複雑な変換を行う、中間の view あるいは ephemeral なモデル。ephemeral は common table expression (CTE) を生成し ref しているモデルに埋め込むため DWH をシンプルに保てるが、直接クエリを実行できない分トラブルシューティングが少し難しい。
ディレクトリはビジネスグループの粒度で切り、ファイル名は int_[entity]s_[verb]s.sql のようにして、何が起こってるかを理解できるようにする。
marts
staging や intermediate のモデルからエンドユーザーが参照するテーブルを作る。ウェイトの大きいコンピューティングコストを節約するため非正規化される。JOIN が多い場合 intermediate でまとめてコンセプトを明確にすると読みやすくなることがある。
ディレクトリはビジネスグループや、興味関心の粒度で切り、ファイル名は customers などのエンティティ名になる。
$ cat dbt_project.yml
...
models:
dbttest:
staging:
+materialized: view
intermediate:
+materialized: ephemeral
marts:
+materialized: table