dbt の Best practice guides におけるモデルのレイヤー分け

dbt

dbt 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