LoginSignup
5
5

More than 1 year has passed since last update.

【データ基盤構築/dbt】modelディレクトリの構成のベストプラクティス

Last updated at Posted at 2023-02-28

今回の課題

dbtのmodelディレクトリの構成のベストプラクティスについて理解しようと思った。
公式ドキュメントを読みながら、自分なりに理解してまとめてみた。

※参考:How we structure our dbt projects

dbtプロジェクトの構成のベストプラクティス

下記のような構成が、推奨されていた。
modelsディレクトリ内に、intermediate, marts, stagingフォルダを作成して管理しているかたちだ。

jaffle_shop
├── README.md
├── analysis
├── data
│   └── employees.csv
├── dbt_project.yml
├── macros
│   └── cents_to_dollars.sql
├── 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
├── packages.yml
├── snapshots
└── tests
    └── assert_positive_value_for_total_amount.sql

Stagingディレクトリについて

stagingディレクトリにはソースデータから、
一次集計を行うためのコードが書かれたmodelを格納する。

1)サブディレクトリの分け方

⭕推奨

データを抽出してくるシステムに応じて、サブディレクトリを作成する。
上記のドキュメントから引用したディレクトリ構成では、
juffle_shopStripeという、2つの異なるシステム毎にディレクトリを分けている。

❌非推奨

  • データのロード方法(Fivetran、Stitchなど)で、サブディレクトリを分ける。
  • 「マーケティング」「ファイナンス」などビジネス上のジャンルで、サブディレクトリを分ける。

2)Stagingディレクトリのmodelの命名規則について

⭕推奨

stg_[source]__[entity]s.sqlといったように、ソースシステムとエンティティの間に、ダブルアンダースコアを使用すると、ソースデータが複数の要素を持つ場合に、視覚的に区別しやすい。
また、entityは複数系で命名するようにした方が良い。

(例)stg_googleanalytics__users.sql, stg_googleanalytics__worksのようなイメージ

❌非推奨

stg_[entity].sqlといった命名は、ファイルの数が少ないうちは良いが増えていくと区別しづらくなる。

3)Stagingディレクトリのmodelで行う主な処理

  • リネーム
  • 型変換
  • 基本的な計算(セントからドルに単位を変換する。など)
  • カテゴライズ(case文で、値をグループ分けする。など)

4)Stagingディレクトリのmodelはビューとして実体化する

下記の理由から、staging modelはviewとして保持した方が良い。

  • staging modelを参照する下流のモデルが常に最新のデータを取得できる
  • ウェアハウス内のストレージの浪費を避けることができる(高速化したい場合は、table化を検討した方がいいかも)

intermediateディレクトリについて

Staging modelで作成したテーブルを、グループ化して異なる粒度で集計するなどする。
intermediateモデルの目的は、martsモデルの複雑さを解消すること。

1)サブディレクトリの分け方

⭕推奨

ビジネス上の関心領域ごとにサブディレクトリを分ける。
(例)financeディレクトリなど

2)intermediateディレクトリのmodelの命名規則について

⭕推奨

int_[entity]s_[動詞]s.sqlといったように命名する。
内部で様々な処理をするので、名前の付け方を厳密に決めるのが難しいが、
最良なのは、実施する処理の動詞(例えばaggregated_to_user, joinedなど)を考慮して付けるのが良い。

3)intermediateディレクトリのモデルはEphemeralとして実体化する

ダッシュボードやアプリケーションなどへの出力をしないため、
intermediate modelのデータは本番環境で公開しない。
データガバナンスと検出可能性を簡単に制御できるように、モデルから分離しておく。
それらの理由から、Ephemeralとして実体化する。

martsディレクトリについて

データマートを生成するためのmodelを作成する。

1)サブディレクトリの分け方

マートの数が少ない場合サブフォルダが不要の可能性があるため、
早急に最適化する必要は無い。
マートが増えてきたら、部門別(finance, marketing)などでグループ化する。

2)martsディレクトリのmodelの命名規則について

customersやordersなど、マートのコンセプトに基づいて分かりやすい名前を付ける。
order_per_dayのように、時間軸は設定しないようにする。

3)martsディレクトリのmodelはtableまたはincrementalとして実体化する

マートを作成するまではテーブル自体の生成はしなかったが、
ここからは実体のあるテーブルを生成する。

実体のあるテーブルをダッシュボードなどに繋げておくことによって、
誰かがダッシュボードにアクセスや更新をする度に、再計算の処理をせずに済む。

まとめ

テーブルの一次処理、統合、データマート作成など、
段階に応じて、命名規則、ディレクトリの分け方、実体化の方法など推奨されていることが異なるということが分かった。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5