dbtで変換ロジックを整理してきたなら、次の自然なステップが「メトリクスの定義」をdbtプロジェクトに引き取ることです。「売上」「アクティブユーザー数」「顧客単価」といった指標を、BIごとに別々で書くのではなく、dbtの中で一元的に定義する。dbt Semantic Layerは、これを実現する機能です。

2022年にTransform社(旧Transform.co)を買収し、彼らのMetricFlowを統合する形で、2023年に正式リリースされました。dbtプロジェクトのコードでメトリクスを定義し、BIや独自アプリから一貫したクエリで参照できます。実装と運用を整理します。

基本概念:Semantic ModelとMetric

dbt Semantic Layerは、2つの概念で組み立てます。

概念役割
Semantic Modelあるdbtモデルを「分析可能な単位」として宣言。entities(主キー)・dimensions(切り口)・measures(数値)を定義
MetricSemantic Modelのmeasureや他のMetricを組み合わせて、ビジネス指標を定義

「Semantic Modelで素材を定義し、Metricで料理する」とイメージすると分かりやすいです。

最小のSemantic Model

# models/semantic/orders.yml
semantic_models:
  - name: orders
    description: 注文ファクトテーブル
    model: ref('fct_orders')

    entities:
      - name: order_id
        type: primary
      - name: customer_id
        type: foreign

    dimensions:
      - name: ordered_at
        type: time
        type_params:
          time_granularity: day
      - name: order_status
        type: categorical

    measures:
      - name: order_total
        agg: sum
        expr: order_total
      - name: order_count
        agg: count
        expr: order_id

これで「fct_orders」を、時間(ordered_at)・状態(order_status)で切り、合計(order_total)と件数(order_count)で測れる「分析可能な単位」として宣言しました。

Metricの定義

# models/semantic/metrics.yml
metrics:
  - name: total_revenue
    label: 売上合計
    type: simple
    type_params:
      measure: order_total
    filter: "{{ Dimension('orders__order_status') }} = 'paid'"

  - name: order_count
    label: 注文件数
    type: simple
    type_params:
      measure: order_count

  - name: avg_order_value
    label: 平均注文単価
    type: ratio
    type_params:
      numerator: total_revenue
      denominator: order_count

`total_revenue`は「`paid`状態の注文だけのorder_total合計」、`avg_order_value`は「売上合計÷注文件数」と、ビジネス用語で定義できます。BIや分析者は、このメトリクス名で問い合わせるだけで一貫した数字が返ってきます。

MetricFlow:SQL生成エンジン

定義したメトリクスは、MetricFlowというエンジンが実行時にSQLに変換します。`mf query`コマンドで動作確認できます。

# 日次の売上合計を問い合わせる
mf query \
  --metrics total_revenue \
  --group-by metric_time__day

# 出力されるSQL(一部)
SELECT
  DATE_TRUNC('day', ordered_at) AS metric_time__day,
  SUM(order_total) AS total_revenue
FROM fct_orders
WHERE order_status = 'paid'
GROUP BY 1

「メトリクス定義」と「実際に走るSQL」が一致するので、BIで見える数字とdbt内の定義が必ず同じになります。

BI連携

dbt Semantic Layerは、JDBC・GraphQL・REST APIで外部から問い合わせられます。主要BIは公式パートナー連携を進めています。

BI/ツール連携状況
TableauTableau dbt Semantic Layer Connector
Hexネイティブ統合
Modeネイティブ統合
Lightdash連携可能
Lookerサードパーティ経由で連携
独自アプリJDBC/GraphQL APIで自由に

BIごとにメトリクスを書く必要がなくなり、「BI間で数字が割れる」根本的な問題が解消されます。

dbt Cloud Enterpriseが必要

dbt Semantic LayerのSaaS機能を本格利用するには、dbt Cloud Enterpriseプランの契約が必要です。OSSのdbt Coreでも、MetricFlowのライブラリを使えばローカルでメトリクス定義は書けます。けれども、JDBC/GraphQL APIによるBI連携やキャッシュは、dbt Cloud側で提供されるサービスです。

環境使える範囲
dbt Core(OSS)MetricFlowでローカル定義・実行のみ
dbt Cloud(無料/Team)限定的
dbt Cloud EnterpriseBI連携・APIフル機能

料金はEnterpriseプランで月数十万円から(規模次第)です。dbt中心の組織で、BI間の数字割れに困っているなら投資価値はありますが、規模に対して過剰投資にならないか判断が必要です。コスト面で合わなければ、Cubeなどの代替を検討します。

運用上のハマりどころ

  • Semantic Modelの設計が難しい:「どこをSemantic Modelにするか」「entitiesとdimensionsの分け方」に経験が要る。最初はdbtコミュニティの例を参考にする。
  • 業務側との定義合意:「売上」の定義(税抜き/税込み、キャンセル含む/除く等)を業務側と合意する工程を省くと、技術的に正しくても業務的に正しくないメトリクスができる。
  • 移行の段階性:すべてのBIメトリクスを一気にSemantic Layer経由に切り替えると混乱する。重要メトリクス数個から段階移行する。
  • パフォーマンス:複雑なメトリクスは生成SQLが重くなる。実行時にプロファイリングし、Gold層の事前集計を活用する。

向く・向かない場面

  • 向く:dbt中心の組織、複数のBIを併用、メトリクス定義をdbtに一元化したい、Tableau/Hex/Modeを使っている、dbt Cloud Enterpriseを契約できる規模
  • 向かない:dbtを使っていない(→Cube)、OSSで自前運用したい(→CubeorLightdash)、Looker中心でLookML運用が回っている

まとめ

  • dbt Semantic Layerは、dbtプロジェクトと一体化したメトリクス定義層。
  • Semantic Model+Metricの2層構造で、MetricFlowがSQL生成。
  • Tableau・Hex・Modeなど主要BIから一貫した数字でアクセスできる。
  • SaaSフル機能はdbt Cloud Enterprise契約が前提。コストと組織規模の見合いで判断。
  • 導入は重要メトリクス数個から段階的に始める。業務側との定義合意がカギ。

全体像はセマンティックレイヤーとメトリクス管理、隣接の選択肢はCube とはLightdash とはにあります。導入や移行の壁打ちは、DE-STKの初回相談(30分・無料)もご利用ください。

よくある質問(FAQ)

Q. dbt CoreだけでSemantic Layerは使えますか?

A. ローカルで定義と実行はできます。`pip install dbt-metricflow`でMetricFlowを入れて、`mf query`コマンドでメトリクスを実行できます。ただし、BIから接続するためのJDBC/GraphQL APIエンドポイントは、dbt Cloud Enterpriseでホストされる形になります。Coreだけだと「定義は書けるけど、BIから使えない」状態です。

Q. 既存のdbtプロジェクトに追加するのは大変ですか?

A. 中規模プロジェクトで2〜4週間が目安です。Semantic Modelの設計、メトリクス定義の業務合意、BI側の接続切り替えが主な作業です。「すべてのモデルにSemantic Modelを付ける」を最初から目指さず、まず重要なファクトテーブル数個から始めるのが現実的です。dbtの実装基本はdbt実装ガイドを参照してください。

Q. Semantic Modelで定義したものは、ダッシュボード以外で使えますか?

A. 使えます。GraphQL APIやJDBCでクエリできるので、独自アプリ、Pythonスクリプト、Slackボットからもメトリクスを参照できます。「KPIアラートをSlackに毎朝投稿する」「LLMがメトリクスを正しい定義で取得する」といった用途にも使えます。これがCubeとの主な競合領域でもあります。

Q. パフォーマンスは大丈夫ですか?

A. SQL生成は一瞬ですが、生成されたSQLが重いと遅くなります。素直なメトリクス(合計・件数)なら問題ありませんが、複雑な比率や時系列の計算は工夫が要ります。Gold層で事前集計したテーブルをSemantic Modelの元にする、dbt Cloudのキャッシュ機能を使う、といった対策で対応します。重いメトリクスを特定したら、Goldマートに集計を逃がす設計判断をします。