dbt ではファイル名がそのままモデル名になり、ref・source・セレクタ・ドキュメントの全てで露出します。つまり命名は開発速度と運用品質に直結します。
本稿は dbt 公式の一般的なベストプラクティスに沿い、stg/int/dim/fct などのレイヤを軸に、実務で迷わない命名レシピと試験で問われやすい観点をまとめます。
dbt のモデル名は小文字スネークケースを基本にし、レイヤを示す短いプレフィックスで始めます。粒度(granularity)が想像できる具体名にし、略語はチームで合意した最小限に抑えます。
特に Analytics Engineer 試験では、stg_{source}_{table} と dim_/fct_ の役割差、セレクタでの絞り込み容易性が問われがちです。
良い/悪い命名の例
# Good
stg_sf_account.sql
int_customer_unified.sql
dim_customer.sql
fct_order_line.sql
rpt_sales_summary.sql
# Bad
StageSalesforceAccount.sql -- uppercase / camel
staging_accounts.sql -- layer name too long / inconsistent
customer_v2_new_new.sql -- meaningless version suffixes
ordersFact.sql -- camel + inconsistent prefixレイヤごとに役割と粒度を固定し、プレフィックスで一目で分かるようにします。stg はソーステーブルと1対1、int は結合や前処理の中間、dim/fct はマート層の配布用という棲み分けが基本です。
プレフィックスはセレクタでの運用に効きます。例えば dbt build -s stg_* や +fct_* など、命名がそのまま対象選択の表現力になります。
| レイヤ | 推奨プレフィックス | 代表例 | 粒度/役割 |
|---|---|---|---|
| Staging | stg_ | stg_sf_account | ソース1対1、列名・型の正規化 |
| Intermediate | int_ | int_customer_unified | 結合・重複排除・キー整備 |
| Dimension | dim_ | dim_customer | ユニークキーで1行=エンティティ |
| Fact | fct_ | fct_order_line | イベント/取引で1行=事実 |
| Report/Mart | rpt_ | rpt_sales_daily | 最終集計・指標配布 |
モデル依存関係とフォルダの対応
models/
staging/
sf/
stg_sf_account.sql
stg_sf_contact.sql
intermediate/
int_customer_unified.sql
marts/
core/
dim_customer.sql
fct_order_line.sql
reporting/
rpt_sales_daily.sql
Flow:
source('sf','account') --> stg_sf_account --> int_customer_unified --> dim_customer
\
--> fct_order_line --> rpt_sales_dailyセレクタ例(CLI で活きる命名)
# stg だけをビルド
dbt build -s stg_*
# fct とその上流をすべて(+ は上流/下流依存)
dbt build -s +fct_*
# 顧客関連だけ(命名の共通部分で束ねる)
dbt build -s dim_customer int_customer_* stg_*_customer*フォルダはレイヤとドメインで二段に切ると、スコープごとの schema.yml を置きやすくなります。YAML 上の name はファイル名(=モデル名)と一致させ、description は BI 利用者向けに簡潔に。
プロジェクトの quoting 設定はデフォルト(未指定=多くのアダプタで非引用)を前提にし、モデル名は小文字で統一します。倉庫によっては実体名が大文字化されますが、論理名(dbt 上の model name)は変わりません。
例: dbt_project.yml と schema.yml
# dbt_project.yml(抜粋)
name: my_dbt
models:
my_dbt:
staging:
+materialized: view
intermediate:
+materialized: table
marts:
core:
+materialized: table
# models/staging/sf/schema.yml(抜粋)
version: 2
models:
- name: stg_sf_account
description: "Salesforce Account の正規化ビュー(1行=アカウント)"
columns:
- name: account_id
tests: [not_null, unique]
- name: account_name
tests: [not_null]
- name: stg_sf_contact
description: "Salesforce Contact の正規化ビュー(1行=人物)"
columns:
- name: contact_id
tests: [not_null, unique]source は組織内で安定した system 名を与え、テーブル側は実体名に合わせます。stg の命名に source 名を入れてトレースできるようにします。
seed は配布用であれば素直なビジネス名、補助マッピングであれば map_ 前置きなどの一貫した流儀を使います。スナップショットは論理名= snapshot ブロック名で、対象テーブルが推測できる明確な名前にします。
source・seed・snapshot の定義例
# models/staging/sf/sources.yml(抜粋)
version: 2
sources:
- name: sf
schema: raw_salesforce
tables:
- name: account
- name: contact
# seeds/proj/map_country_codes.csv -> map_country_codes テーブルに
# dbt_project.yml(抜粋)
seeds:
+schema: reference
proj:
+quote_columns: false
# snapshots/snap_customer_scd2.sql(抜粋)
{% snapshot snap_customer_scd2 %}
{{ config(
target_schema='history',
unique_key='customer_id',
strategy='check',
check_cols=['email','status']
) }}
select * from {{ ref('dim_customer') }}
{% endsnapshot %}汎用テスト(unique, not_null 等)は YAML で宣言すれば dbt が一貫したテスト名を生成します。独自ロジックは singular テスト(tests ディレクトリの SQL)にし、test_{対象}_{規則} のように名付けます。
マクロは用途を接頭辞で分け、型変換やクリーニング系は util_、ビジネスルールは biz_ など役割が分かる名にします。exposure は BI ダッシュボード単位で exposure_{領域}_{名称} とし、depends_on のモデル名と整合を取ります。
テストとマクロの例
# models/marts/core/schema.yml(抜粋)
version: 2
models:
- name: dim_customer
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns: [customer_id]
columns:
- name: email
tests: [not_null]
# tests/test_dim_customer_email_format.sql(singular)
select email from {{ ref('dim_customer') }}
where email !~ '^[^@]+@[^@]+\.[^@]+
NicheeLab を読み込み中…
#x27; # macros/util_clean_email.sql {% macro util_clean_email(col) %} lower(trim({{ col }})) {% endmacro %} # models/staging/sf/stg_sf_contact.sql(利用例) select contact_id, {{ util_clean_email('email') }} as email from {{ source('sf','contact') }}
アンチパターンは、意味のないバージョン接尾辞、抽象的すぎる名前、レイヤ不一致(例: stg で重結合)です。命名で粒度と責務を裏切るとドキュメントと現物が乖離します。
レガシー互換のために倉庫側のテーブル名を合わせる必要があるときだけ alias を使います。論理名(ファイル名)は規約通り、物理名だけ alias で置き換えると影響を局所化できます。
alias と引用設定の例
# models/marts/core/dim_customer.sql
{{ config(alias='DIM_CUSTOMER_LEGACY') }}
select * from {{ ref('int_customer_unified') }}
# dbt_project.yml(抜粋: Snowflake 等で大文字化を避けたい場合)
quoting:
database: false
schema: false
identifier: true # 物理名を引用して大文字化を防ぐ
# 注: 倉庫やアダプタのデフォルト挙動に依存するため、チームで合意の上で設定するAnalytics Engineer
問題 1
Salesforce の Account と Contact を 1:1 正規化した上で顧客の統合ビューを作成し、最終的にディメンションを配布したい。適切な命名の組み合わせはどれか。
正解: A
stg でソースと 1:1 を守り、int で統合・重複排除し、配布は dim_ に載せるのが原則。A はプレフィックスと粒度の整合が取れている。
dim と fct のどちらを単数/複数で名付けるべきですか?
粒度が 1 行=エンティティの dim は単数(dim_customer)、1 行=イベント/取引の fct は複数でも単数でも構いませんが、プロジェクト全体で統一してください(fct_order_line など粒度が読める名を推奨)。
バージョン違いのモデルを並行運用したい場合、名前に v2 を付けても良いですか?
恒常運用には推奨しません。移行期間のみ限定で int_customer_unified_v2 のように付け、Issue/PR でサンセット計画を明記し、エイリアスまたはビューで互換名を提供する方が安全です。恒久化は避けてください。
倉庫側で自動大文字化されます。dbt の命名規則に影響しますか?
論理名(ref で使う model name)は変わりません。物理名の大文字化を避けたい場合はプロジェクトの quoting.identifier を true にします。いずれにせよ、ファイル名は小文字スネークで統一してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
dbt Model の基礎: SQL で定義する変換の最小単位
Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...
dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点
dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...
dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点
dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...
dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト
Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....
dbt_project.yml の読み方:主要設定と命名を最短で掴む
dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...