Databricksで構築するRedditデータパイプライン⑤ メトリクスビューによるセマンティックレイヤー
はじめに
前回(第4回)でパイプラインの基本構築は完了しました。今回からは発展編として、DatabricksのUnity Catalog メトリクスビューを紹介します。
第4回で作成したダッシュボードでは、Gold層のテーブルに直接クエリを書いていました。しかし、ダッシュボードが増えると、集計ロジックの散在やカラム名の不統一が問題になります。
メトリクスビューは、これらの問題を解決するセマンティックレイヤーを提供します。
メトリクスビューとは
公式ドキュメント
詳細は公式ドキュメントを参照してください。
ひとことで言うと
メトリクスビューは、dimensions(分析軸) と measures(集計値) を定義し、データモデルに意味付けを行う仕組みです。
なぜ必要なのか
| 問題 | Gold層だけの場合 | メトリクスビュー導入後 |
|---|---|---|
| 集計ロジックの散在 | 各ダッシュボードで同じSUMを書く | メトリクスビューに一元化 |
| カラム名の不統一 |
sum_upvote vs total_upvote
|
display_name で統一 |
| 動的な分析軸の追加 | テーブル定義の変更が必要 | メトリクスビュー内で動的計算可能 |
本プロジェクトでの位置づけ
第3回で構築したDim/Factテーブルの上に、メトリクスビューを追加します。
Silver層
│
├──▶ Dim層
│ dim_calendar, dim_subreddit, dim_post
│
└──▶ Fact層
fact_subreddit_daily, fact_post_daily
│
├──▶ Gold層(BI向け)
│ gold_subreddit_daily, gold_top_posts_daily
│
└──▶ メトリクスビュー(セマンティックレイヤー) ← NEW!
reddit_metric_view
Gold層とメトリクスビューは併用します。用途に応じて使い分けます。
| 用途 | 使うもの |
|---|---|
| 固定のダッシュボード | Gold層テーブル |
| 新しい集計軸の試行錯誤 | メトリクスビュー |
| 複雑なレポート(非定型) | メトリクスビュー |
メトリクスビューの作成
メトリクスビューはSQLエディタで直接作成できます。Databricks SQLのクエリエディタを開き、以下のSQLを実行するだけです。
SQLエディタで実行
USE CATALOG reddit;
USE SCHEMA sdp;
CREATE OR REPLACE VIEW reddit_metric_view
WITH METRICS
LANGUAGE YAML
AS $$
version: 1.1
source: fact_subreddit_daily
joins:
- name: dim_calendar
source: dim_calendar
on: source.date_id = dim_calendar.date_id
- name: dim_subreddit
source: dim_subreddit
on: source.subreddit_id = dim_subreddit.subreddit_id
dimensions:
- name: subreddit
expr: dim_subreddit.subreddit
comment: サブレディット名(分析の主軸)
display_name: サブレディット
- name: calendar_date
expr: dim_calendar.calendar_date
comment: データ取込日
display_name: 取込日
format:
type: date
date_format: year_month_day
leading_zeros: false
- name: year
expr: dim_calendar.year
comment: 取込日の年
display_name: 年
- name: month
expr: dim_calendar.month
comment: 取込日の月
display_name: 月
- name: day
expr: dim_calendar.day
comment: 取込日の日
display_name: 日
- name: year_month
expr: dim_calendar.year_month
comment: 年月(YYYY-MM形式)
display_name: 年月
- name: day_of_week
expr: dayofweek(dim_calendar.calendar_date)
comment: 曜日(1=日曜, 7=土曜)
display_name: 曜日
- name: is_weekend
expr: dayofweek(dim_calendar.calendar_date) IN (1, 7)
comment: 週末フラグ(土日)
display_name: 週末フラグ
measures:
- name: total_post_count
expr: SUM(post_count)
comment: 投稿数の合計
display_name: 投稿数_合計
- name: total_row_count
expr: SUM(row_count)
comment: レコード数の合計
display_name: レコード数_合計
- name: total_upvote
expr: SUM(sum_upvote)
comment: Upvote数の合計
display_name: Upvote数_合計
- name: avg_upvote_per_post
expr: AVG(avg_upvote)
comment: 1投稿あたりの平均Upvote数
display_name: Upvote数_投稿平均
- name: avg_comment_upvote
expr: AVG(avg_comment_upvote)
comment: コメントの平均Upvote数
display_name: コメントUpvote_平均
$$;
実行後、Catalog Explorerで reddit.sdp.reddit_metric_view が作成されていることを確認できます。
YAML定義の解説
| 要素 | 説明 |
|---|---|
source |
メインとなるFactテーブル |
joins |
Dimensionテーブルとの結合定義 |
dimensions |
分析軸(フィルタ・グループ化に使用) |
measures |
集計値(SUM, AVG, COUNT等) |
display_name |
UIで表示される名前 |
comment |
説明文 |
format |
表示形式(日付のフォーマット等) |
expr |
計算式(元テーブルのカラムや関数を使用) |
動的計算の例
day_of_week と is_weekend は、dim_calendar テーブルに存在しないカラムです。メトリクスビュー内で動的に計算しています。
# 元テーブルにないカラムも定義可能
- name: day_of_week
expr: dayofweek(dim_calendar.calendar_date) # 関数で動的計算
comment: 曜日(1=日曜, 7=土曜)
display_name: 曜日
💡 本来は事前計算が望ましい
日付関連の属性は頻繁に使うため、
dim_calendarに事前計算しておく方がパフォーマンス面で有利です。今回は「メトリクスビューでも動的計算できる」ことを示すためにあえてこの形にしています。
(オプション)DABsによるデプロイ
メトリクスビューをAsset Bundleで管理したい場合は、ノートブック化してJobとしてデプロイできます。
ディレクトリ構成
reddit-pipeline/
├── src/
│ └── metric_views/
│ └── metric_view_creation.sql
└── resources/
└── reddit_metric_views_setup_job.yml
src/metric_views/metric_view_creation.sql
パラメータ化するために identifier() 関数を使用します。Lakeflow Declarative Pipelinesのノートブックと同様に、MAGICコマンドなしで純粋なSQLで記述できます。
-- Databricks notebook source
USE CATALOG identifier(:catalog);
USE SCHEMA identifier(:schema);
-- COMMAND ----------
CREATE OR REPLACE VIEW reddit_metric_view
WITH METRICS
LANGUAGE YAML
AS $$
version: 1.1
source: fact_subreddit_daily
joins:
- name: dim_calendar
source: dim_calendar
on: source.date_id = dim_calendar.date_id
- name: dim_subreddit
source: dim_subreddit
on: source.subreddit_id = dim_subreddit.subreddit_id
dimensions:
- name: subreddit
expr: dim_subreddit.subreddit
comment: サブレディット名(分析の主軸)
display_name: サブレディット
- name: calendar_date
expr: dim_calendar.calendar_date
comment: データ取込日
display_name: 取込日
format:
type: date
date_format: year_month_day
leading_zeros: false
- name: year
expr: dim_calendar.year
comment: 取込日の年
display_name: 年
- name: month
expr: dim_calendar.month
comment: 取込日の月
display_name: 月
- name: day
expr: dim_calendar.day
comment: 取込日の日
display_name: 日
- name: year_month
expr: dim_calendar.year_month
comment: 年月(YYYY-MM形式)
display_name: 年月
- name: day_of_week
expr: dayofweek(dim_calendar.calendar_date)
comment: 曜日(1=日曜, 7=土曜)
display_name: 曜日
- name: is_weekend
expr: dayofweek(dim_calendar.calendar_date) IN (1, 7)
comment: 週末フラグ(土日)
display_name: 週末フラグ
measures:
- name: total_post_count
expr: SUM(post_count)
comment: 投稿数の合計
display_name: 投稿数_合計
- name: total_row_count
expr: SUM(row_count)
comment: レコード数の合計
display_name: レコード数_合計
- name: total_upvote
expr: SUM(sum_upvote)
comment: Upvote数の合計
display_name: Upvote数_合計
- name: avg_upvote_per_post
expr: AVG(avg_upvote)
comment: 1投稿あたりの平均Upvote数
display_name: Upvote数_投稿平均
- name: avg_comment_upvote
expr: AVG(avg_comment_upvote)
comment: コメントの平均Upvote数
display_name: コメントUpvote_平均
$$;
resources/reddit_metric_views_setup_job.yml
resources:
jobs:
reddit_metric_views_setup_job:
name: reddit-metric-views-setup-${bundle.target}
parameters:
- name: catalog
default: ${var.catalog}
- name: schema
default: ${var.schema}
tasks:
- task_key: metric_view_setup
notebook_task:
notebook_path: ../src/metric_views/metric_view_creation.sql
base_parameters:
catalog: "{{job.parameters.catalog}}"
schema: "{{job.parameters.schema}}"
source: WORKSPACE
environments:
- environment_key: default
spec:
environment_version: "4"
デプロイと実行
databricks bundle deploy
databricks bundle run reddit_metric_views_setup_job
💡 なぜ
bundle runが必要なのか?
databricks bundle deployはJobの定義をWorkspaceに登録するだけで、Jobを実行はしません。Lakeflow Pipelinesの場合はスケジュールを設定しているため、deploy後に自動で定期実行されます。しかし、メトリクスビューのセットアップJobは一度実行すればビューが作成されるため、スケジュールを設定していません。そのため、初回セットアップ時に手動で
bundle runを実行する必要があります。
項目 Lakeflow Pipelines メトリクスビューJob 目的 データを継続的に処理 ビュー定義を1回作成 スケジュール あり(定期実行) なし(初回のみ) bundle deploy後スケジュールで自動実行 手動で runが必要
メトリクスビューの活用
1. Databricks SQLからのクエリ
メトリクスビューをクエリする際は、measures(集計値)に MEASURE() 関数を使用する必要があります。
-- subreddit別の月次サマリ
SELECT
subreddit,
year_month,
MEASURE(total_post_count) AS total_post_count,
MEASURE(total_upvote) AS total_upvote,
MEASURE(avg_upvote_per_post) AS avg_upvote_per_post
FROM reddit_metric_view
WHERE year = 2025
GROUP BY subreddit, year_month
ORDER BY year_month, total_upvote DESC;
💡 MEASURE() 関数について
メトリクスビューの
measuresはSUMやAVGなどの集計関数を含むため、通常のカラムとは異なります。MEASURE()関数で囲むことで、メトリクスビューが定義した集計ロジックが適用されます。また、
GROUP BYで集計軸(dimensions)を指定する必要があります。これにより、どの粒度で集計するかを明示します。
2. ダッシュボードでの利用
AI/BI dashboardsでメトリクスビューをデータソースとして選択すると、dimensionsとmeasuresが明確に分かれて表示されます。これにより、グラフ作成時に「どのカラムをX軸に使うか」「どのカラムを集計するか」が直感的に選べます。
ダッシュボードでは MEASURE() 関数を意識する必要はなく、UIで measures を選択するだけで自動的に適切な集計が行われます。
今回のまとめ
発展編として、Unity Catalog メトリクスビューによるセマンティックレイヤーの構築を解説しました。
メトリクスビューのメリット:
| メリット | 説明 |
|---|---|
| 集計ロジックの一元化 |
measures でSUM/AVG等を定義 |
| カラム名の統一 |
display_name でUI表示名を統一 |
| 動的な分析軸 |
expr で元テーブルにない計算も定義可能 |
構成のポイント:
| 要素 | 本プロジェクトでの設定 |
|---|---|
| source | fact_subreddit_daily |
| joins |
dim_calendar, dim_subreddit
|
| dimensions | subreddit, calendar_date, year等 |
| measures | total_post_count, total_upvote等 |
メトリクスビューを導入することで、第4回で作成したダッシュボードの基盤がより堅牢になります。
シリーズ目次:
- 概説 & プロジェクト準備
- データ取得の基本設計
- Lakeflow Spark Declarative Pipelines(Bronze→Silver→Gold)
- ダッシュボード & 運用
- メトリクスビューによるセマンティックレイヤー(本記事)
- Genieを使った分析
Discussion