dbt で「信頼できる KPI 定義」を作る
Stage 1 — 第1章 | dbt入門カリキュラム 推定学習時間:30〜40分 | 難易度:★★☆☆☆
この章で学ぶこと
データマネジメント入門 では、指標の定義がバラけると会議が前に進まない、という話をしました。 dbt Core は、その「定義をコードとして固定する」ための Transform 層 を作る OSS です。
この章では、dbt が 何をするツールか を先に整理し、そのうえで DS Playground の分析プロジェクトを 読み解く前提 を押さえます。
手元で dbt run を実行する章ではありませんが、SQL と YAML の 読み方 はここから始めます。
この章を終えると、こんなことができるようになります:
- dbt Core が ELT のどの部分を担当するか説明できる
- ad-hoc SQL だけでは KPI 定義がブレる理由を説明できる
ref()で依存関係を宣言する意味を説明できる- 次章以降で出てくる staging / mart の 役割分担 を概観できる
dbt とは何をするツールか
Web アプリや学習サービスは、日々の利用データを 本番データベース(OLTP) に書き込みます。 分析チームはそのデータを集計し、ダッシュボードで KPI を見ます。
ここでよくある構成が ELT です。
- Extract(E) … アプリ DB などからデータを取り出す
- Load(L) … 分析用のデータベース(DWH / analytics schema)に載せる
- Transform(T) … SQL で整形・結合・集計し、分析向けテーブルを作る
dbt Core は 3 の T を担当します。 BI ツール(Metabase など)の代わりではなく、BI が読む 分析用テーブル(mart)を SQL で定義する ためのフレームワークです。
データ取り込み"] L["Load
分析用 DB へ"] T["Transform
dbt Core"] end APP["Web アプリ"] --> E E --> L L --> T T --> MART["mart / view / table"] MART --> BI["BI ツール"] BI --> DASH["ダッシュボード"]
dbt プロジェクトでは、Transform の中身を モデル と呼びます。 1 モデル = 1 つの SQL ファイル(または seed)で、フォルダ名がだいたい次の役割を表します。
| レイヤー | 典型フォルダ | 役割 |
|---|---|---|
| staging | models/staging/ |
ソースに近い 薄い 正規化。列名・型・日付の統一 |
| intermediate | models/intermediate/ |
複数ソースを統合し、ビジネス定義 を固定 |
| marts | models/marts/ |
BI が読む 完成表。1 表 ≒ 1 ビジネス問い |
YAML ファイル(schema.yml など)には、列の説明や test(品質チェック)を書きます。
SQL だけでなく YAML も Git で管理するのが、dbt の「定義を共有する」部分です。
ad-hoc SQL だけでは KPI がブレる
SQL が書ける人が増えると、ダッシュボード用 SQL が個人 PC や BI 上に増えていきます。 その状態では、同じ KPI 名でも中身が違う ことが起きます。
たとえば「アクティブユーザー」を数える SQL が、
- ログイン回数で数える版
- 問題保存・演習完了など 学習行動 で数える版
の 2 本ある、というのはよくあるパターンです。 どちらも一見「正しそう」ですが、会議では数字が合いません。
dbt では、こうした定義を intermediate モデル 1 か所 に置き、下流は ref('そのモデル名') するだけにします。
「この KPI の正本はどのモデルか」がコード上で固定される、というのが出発点です。
| 観点 | ad-hoc SQL | dbt プロジェクト |
|---|---|---|
| 保存場所 | 個人メモ、BI、スプレッドシート | Git |
| 依存関係 | 口頭・コメント | ref() / source() |
| 品質 | 実行して初めて気づく | test を CI で実行 |
| 変更 | 影響範囲が見えにくい | lineage / PR レビュー |
DS Playground ではどうしているか
DS Playground の社内分析(analytics_mcp の dbt プロジェクト)も、上の 3 レイヤー構成です。
Supabase 上のアプリデータを source() で読み、staging → intermediate → marts を経て、社内 BI で KPI を見ます。
アクティブユーザー は、ログインではなく 明示的な学習行動(問題保存、カリキュラム完了など)で定義しています。
その定義の SSOT(Single Source of Truth)は intermediate の int_user_activity_events です。
-- 採用しない例: セッション由来
SELECT COUNT(DISTINCT user_id) AS dau
FROM user_sessions
WHERE session_date = CURRENT_DATE;
-- プロジェクトの SSOT
SELECT COUNT(DISTINCT user_id) AS dau
FROM int_user_activity_events
WHERE date_day = CURRENT_DATE;
下流の mart(例: 日次アクティブユーザー集計)は、この intermediate を ref() するだけに設計されています。
Metabase 側で別定義の SQL を増やさない、という 運用の約束 とセットで効きます。
会員数・Premium 状態・問題品質など、他の KPI も同じ考え方です。 「どの mart がどの問いに答えるか」は Stage 3 以降で順に読んでいきます。
他のプロダクトへの当てはめ
EC なら「閲覧・カート・購入」、SaaS なら「機能利用・設定変更」、メディアなら「記事閲覧・会員登録」が、DS Playground の「学習行動イベント」に相当します。 業種が違っても、生テーブルを BI に直結せず、intermediate で定義を固定する 順序は同じです。
体系コラム:カリキュラム上の位置づけ
| 項目 | 内容 |
|---|---|
| Stage / 章 | Stage 1 — 第1章 |
| 今回の論点 | KPI 定義を Transform 層に置く。dbt はその実装 |
| 前章との接続 | データマネジメント入門 — SSOT の「なぜ」 |
| 次章への伏線 | dbt はデータ可視化基盤のどこにいるのか |
まとめ
dbt Core は「SQL が書ける人向けの便利ツール」ではなく、指標定義をコード・test・docs で固定する Transform 層です。 DS Playground のプロジェクトは、その考え方の 実例 として以降の章で読んでいきます。
関連教材
- 次章: dbt はデータ可視化基盤のどこにいるのか
- 関連(DM): 信頼できるデータがないと起きること
- 関連(Analytics): データマート設計
確認問題
問題 1
dbt Core が ELT のうち 主に担当する 部分はどれですか。
A. Extract(データ取り込み)
B. Load(分析用 DB への載せ替え)
C. Transform(SQL による整形・集計)
D. BI 上のグラフ描画
正解: C
解説: dbt は Transform 層です。取り込みパイプライン本体や BI の描画は別コンポーネントの役割です。
問題 2
staging 層 に入れる処理として、最も適切なのはどれですか。
A. 生テーブルの列名・型を軽く整える
B. 売上 KPI の最終定義を確定する
C. ダッシュボード専用の月次集計表を作る
D. 施策効果の解釈を文章で書く
正解: A
解説: staging は薄い正規化の層です。KPI 定義や集計は下流の intermediate / marts に任せます。
問題 3
{{ ref('fct_orders_daily') }} が示すものとして、最も近いのはどれですか。
A. 外部 API への HTTP 呼び出し
B. このモデルが別の dbt モデルに 依存している という宣言
C. BI ダッシュボードの ID
D. CSV seed ファイルのパス
正解: B
解説: ref() は依存グラフ(DAG)をコード化します。build 順序と lineage の正本になります。
用語メモ(この章)
| 用語 | 意味(この章での使い方) |
|---|---|
| dbt Core | Transform を SQL プロジェクトとして管理する OSS |
| ELT | 取り込み・載せ替えの後、分析用 DB 内で SQL 変換する方式 |
| SSOT | 組織が合意した唯一の参照モデル |
| staging / intermediate / marts | 変換の 3 段階(薄い正規化 → 定義固定 → BI 向け完成表) |
ref() |
他モデルへの依存を宣言する dbt 構文 |