メトリクスビューのモデリング
メトリクスビューは、データをセマンティックレイヤー化し、テーブルとビューを標準化されたビジネスメトリクスに変換します。これらは、測定対象、集計方法、およびセグメント化する方法を定義します。その結果、組織内のすべてのユーザーは同じKPIに対して同じ値を報告するため、一貫性のないレポート作成がなくなり、あらゆるフィールドで柔軟な分析が可能になります。
定義するコアコンポーネントは、ソース、結合、フィルター、フィールド、およびメジャーです。
結合、フィールド、メジャー、およびエージェントのメタデータを含む完全な例については、チュートリアル: 結合とデータモデリングを使用したメトリクスビューの構築を参照してください。
コアコンポーネント
メトリクスビューは次の要素で構成されます。
コンポーネント | 説明 | 例 |
|---|---|---|
ソース | データを含む基になるテーブル、ビュー、またはSQLクエリー。 |
|
テーブルのJOIN | テーブル、ビュー、およびメトリックビュー間のエンリッチデータに関する関係。 |
|
フィルター | スコープを定義するためにソースデータに適用される条件。 |
|
フィールド | メトリクスをグループ化、フィルタリング、および集計するために使用される列です。カテゴリ列と、集計されていない数値列が含まれます。ディメンションとも呼ばれます。 | 製品カテゴリ、注文月、単価 |
メジャー | メトリクスを生成する列集計。 |
|
ソースを定義
テーブルのようなアセットまたはSQLクエリーをメトリクスビューのソースとして使用できます。参照されたアセットに対して少なくともSELECTの権限が必要です。
「テーブルのようなアセット」とは、表形式スキーマを公開し、テーブル、ビュー、マテリアライズドビュー、ストリーミングテーブル、フォーリンテーブル、システムテーブル、メトリクスビューを含む クエリーをサポートするUnity Catalogオブジェクトのことです。SELECT
テーブルのようなアセットをソースとして使用する
テーブルのようなアセットをソースとして使用するには、完全修飾名を指定します。例えば、samples.tpch.ordersです。
メトリクスビューをソースとして使用する
既存のメトリクスビューを新しいメトリクスビューのソースとして使用できます:
version: 1.1
source: views.examples.source_metric_view
fields:
- name: Order month
expr: '`Order Month`'
measures:
- name: Latest order month
expr: MAX(`Order month`)
- name: Latest order year
expr: "DATE_TRUNC('year', MEASURE(`Latest order month`))"
メトリクスビューをソースとして使用する場合、フィールドとメジャーを参照する際に同じ構成可能性ルールが適用されます。構成可能性をご覧ください。
SQL クエリーをソースとして使用します
SQLクエリーを使用するには、クエリーテキストをYAMLに直接記述します:
version: 1.1
source: SELECT * FROM samples.tpch.orders o LEFT JOIN samples.tpch.customer c ON o.o_custkey
= c.c_custkey
fields:
- name: Order key
expr: o_orderkey
measures:
- name: Order Count
expr: COUNT(o_orderkey)
SQLクエリーをJOIN句を持つソースとして使用する場合、基になるテーブルに主キー制約と外部キー制約を設定し、最適なクエリーパフォーマンスのためにRELYオプションを使用してください。主キー、外部キー、および一意性制約を宣言すると主キーと一意性制約を使用したクエリーの最適化を参照してください。
ソース内の配列とマップを解決する
フィールド、メジャー、および結合はすべて、フラットなスカラー列に対して動作します。ソースデータに ARRAY または MAP 型の列がある場合は、メトリクスビューの他の場所で参照する前に、source クエリー内でそれらをフラットな列に解決してください。配列要素ごとに 1 行にするか、ソース行ごとに単一の値にするかに応じて、2 つの変換戦略があります。どちらも、配列が最上位のソースにあるか、結合先のテーブルにあるかに関係なく適用されます。変換関数の完全なセットについては、複雑なデータ型の変換を参照してください。
samples カタログ内のどのデータセットにも配列列がないため、このセクションの例では line_items の構造体の配列を持つ orders ビューを使用します。次の例を使用して、配列であるフィールドを持つビューを作成します。catalog.schema を、書き込み先のカタログとスキーマに置き換えます。そのスキーマ内にオブジェクトを作成する権限が必要です。
CREATE OR REPLACE VIEW catalog.schema.orders AS
SELECT
o.o_orderkey,
o.o_custkey,
o.o_orderdate,
o.o_orderstatus,
collect_list(named_struct(
'product_id', l.l_partkey,
'quantity', cast(l.l_quantity as int)
)) AS line_items
FROM samples.tpch.orders o
JOIN samples.tpch.lineitem l ON o.o_orderkey = l.l_orderkey
GROUP BY o.o_orderkey, o.o_custkey, o.o_orderdate, o.o_orderstatus;
配列を行にフラット化する
各配列要素を独自の行として分析するには、source クエリーで explode() を使用して配列を展開します。各要素が個別の行になり、ソース行の他の列が各要素に対して繰り返されます。マップまたは配列からネストされた要素を分解するを参照してください。
次の例では line_items 配列を展開し、各項目が行になるようにします:
version: 1.1
source: |
SELECT o_orderkey, o_custkey, item.product_id, item.quantity
FROM catalog.schema.orders
LATERAL VIEW explode(line_items) AS item
fields:
- name: Product
expr: product_id
measures:
- name: Total quantity
expr: SUM(quantity)
- name: Line item count
expr: COUNT(1)
source で配列を分解するとソース行が増加するため、COUNT(1) のような集計では元の行ではなく配列の要素がカウントされます。ファンアウトなしで元の行も測定するには、代わりに分解されたテーブルを one_to_many 結合としてモデル化します。「1対多の結合」を参照してください。
配列を単一の値に集計する
行数を変更せずに配列をソース行ごとに 1 つの値に削減するには、source クエリーで aggregate()、array_size()、または reduce() などのスカラー配列関数を適用します。各ソース行はその粒度を保持し、コンピュートされた列はフィールドおよびメトリクスで使用できます。
次の例では、注文ごとの line_items 配列のアイテム数と合計数量をコンピュートします:
version: 1.1
source: |
SELECT o_orderkey, o_custkey,
array_size(line_items) AS item_count,
aggregate(line_items, 0, (acc, x) -> acc + x.quantity) AS total_quantity
FROM catalog.schema.orders
measures:
- name: Total quantity
expr: SUM(total_quantity)
- name: Average items per order
expr: AVG(item_count)
ソースクエリーはメトリクスビューが処理する前に配列を削減するため、ソースは注文ごとに 1 行を保持し、メトリクスは通常通り注文全体で集計されます。
結合されたテーブル内の配列を解決する
配列が最上位のソースではなく、結合対象のテーブル内に存在する場合も、同じルールが適用されます。結合はフラットな列に対して動作するため、結合の前に、結合されたテーブル独自のsourceサブクエリー内で配列を解決してください。配列をフラット化または集計するSQLクエリーとして結合sourceを記述し、結果の列で結合します。「メトリクスビューでの結合」を参照してください。
以下の例では customer をソースとして使用し、orders ビューと cardinality: one_to_many を結合しています。結合 source は、結合前に各注文の line_items 配列をスカラー total_quantity に集計するため、メトリクスビューは顧客行を重複させることなく顧客ごとに合計できます:
version: 1.1
source: samples.tpch.customer
joins:
- name: orders
source: |
SELECT o_orderkey, o_custkey,
aggregate(line_items, 0, (acc, x) -> acc + x.quantity) AS total_quantity
FROM catalog.schema.orders
on: orders.o_custkey = source.c_custkey
cardinality: one_to_many
fields:
- name: Customer name
expr: c_name
measures:
- name: Total quantity
expr: SUM(orders.total_quantity)
- name: Order count
expr: COUNT(orders.o_orderkey)
代わりに各配列要素を結合テーブル内の独自の行として扱うには、同様の方法で結合 source 内の explode() を使用して配列をフラット化します。配列を行にフラット化するを参照してください。
フィールド
フィールド(ディメンションとも呼ばれます)は、クエリー時にSELECT、WHERE、およびGROUP BY句で使用できるメトリクスビュー列です。フィールドは、地域やステータスなどのカテゴリ列、または価格や数量などの非集計数値列で、クエリー時に集計できます。各フィールド式はスカラー値を返す必要があります。ソースデータからの列、またはメトリクスビューで以前に定義されたフィールドを参照できます。各フィールドは2つのコンポーネントで構成されています:
name:列のエイリアスexpr:ソースデータまたはメトリクスビューで以前に定義されたフィールドを参照するSQL式
文字列のようなメトリクスビューフィールドは、ソース列がCHARまたはVARCHARの場合でも、常にSTRINGです。CHAR(n)のスペースパディングが失われるため、比較で異なる結果が返される可能性があります。例えば、column = 'COLLEGE'はソーステーブル(スペースで埋め込まれている)のCHAR(10)値とは一致しますが、メトリクスビューフィールドでは一致しません。
メジャー
メジャーは、事前に決定された集計レベルなしに結果を生成する式です。それらは集計関数を使用して表現する必要があります。クエリーでメジャーを参照するには、MEASURE関数を使用します。メジャーは、ソースデータ内のベース列、以前に定義されたフィールド、または以前に定義されたメジャーを参照できます。各メジャーは次のコンポーネントで構成されます:
name:メジャーのエイリアス。expr:SQL集計関数を含むことができる集計SQL式
次の例では、注文および収益データを分析するための一般的なメジャーパターンを示します。これらの例では、注文価格(o_totalprice)、顧客識別子(o_custkey)、注文キー(o_orderkey)、注文日(o_orderdate)、および優先度レベル(o_orderpriority)を含む売上トランザクションデータが含まれるTPC-H注文テーブルを使用します:
measures:
# Simple count measure
- name: Order Count
expr: COUNT(1)
# Sum aggregation measure
- name: Total Revenue
expr: SUM(o_totalprice)
# Distinct count measure
- name: Unique Customers
expr: COUNT(DISTINCT o_custkey)
# Calculated measure combining multiple aggregations
- name: Average Order Value
expr: SUM(o_totalprice) / COUNT(DISTINCT o_orderkey)
# Filtered measure with WHERE condition
- name: High Priority Order Revenue
expr: SUM(o_totalprice) FILTER (WHERE o_orderpriority = '1-URGENT')
# Measure using a field
- name: Average Revenue per Month
expr: SUM(o_totalprice) / COUNT(DISTINCT DATE_TRUNC('MONTH', o_orderdate))
集計関数の一覧については、「集計関数」を参照してください。
フィルターを適用
フィルターは、メトリクスビューを参照するすべてのクエリーに適用されます。UIでフィルターを定義するには、ステップ3: フィルターを定義するを参照してください。
YAML定義でフィルターを定義するには、Boolean式を記述します。次の例は、一般的なフィルターパターンを示しています:
# Single condition
filter: o_orderdate > '2024-01-01'
# Multiple conditions
filter: o_orderdate > '2024-01-01' AND o_orderstatus = 'F'
# IN clause
filter: o_orderstatus IN ('F', 'P') AND o_orderdate >= '2024-01-01'
結合の操作
メトリクスビューは結合をサポートしており、ソースデータを関連テーブルの属性で豊かにすることができます。スタースキーマ(ファクトテーブルをディメンションテーブルに結合したもの)、スノーフレークスキーマ(多層ディメンション結合)、および一対多関係(ディメンショナルソースからのファクト展開)をモデル化できます。結合タイプ、カーディナリティ、スキーマパターン、および制限事項の詳細については、「メトリクスビューの結合」を参照してください。
UIで結合を定義するには、ステップ2:結合の追加を参照してください。YAML定義で結合を定義するには、以下のセクションのパターンを使用します。
結合されたテーブルには、ARRAY 型または MAP 型の列を含めることはできません。結合の前に配列またはマップをフラットな列に解決するには、ソース内の配列とマップの解決を参照してください。
スタースキーマのモデリング
スタースキーマでは、sourceはファクトテーブルであり、LEFT OUTER JOINを使用して1つ以上のディメンションテーブルと結合します。メトリクスビューは、選択したフィールドとメジャーに基づいて、特定のクエリーに必要なファクトテーブルとディメンションテーブルを結合します。
結合列は、on句 (Boolean式) または using句 (共有列名) のいずれかを使用して指定します。結合は多対一のリレーションシップに従う必要があります。多対多の場合、エンジンは結合されたディメンションテーブルから最初に一致する行を選択します。
次の例では、orders (ファクトテーブル) を customer (ディメンションテーブル) に結合し、顧客属性をフィールドとして公開します。rely.at_most_one_match: true を設定すると、結合が多対一 (各注文には顧客が 1 人だけ) であることが宣言され、結合されたテーブルのフィールドでフィルタリングするクエリーをエンジンが最適化できるようになります。
リレーションシップが多対一の場合にのみat_most_one_match: trueを設定します。このプロパティはランタイム時に検証されません。結合によってファンアウトが発生する場合、メトリクスは誤った結果を返します。
「relyによる結合の最適化」を参照してください。
version: 1.1
source: samples.tpch.orders
joins:
- name: customer
source: samples.tpch.customer
on: source.o_custkey = customer.c_custkey
fields:
- name: Customer name
expr: customer.c_name
measures:
- name: Total revenue
expr: SUM(o_totalprice)
YAMLの構文と書式設定
メトリクスビューの定義は、標準のYAML表記構文に従います。必要な構文と書式設定については、メトリクスビューYAML 構文リファレンスを参照してください。
ベストプラクティス
メトリクスビューをモデリングする際は、以下のガイドラインを使用してください:
- Atomicメジャーのモデル化 : まず、最も単純なメジャー(例:
SUM(revenue)、COUNT(DISTINCT customer_id))から定義を開始します。構成可能性を使用して複雑なメジャーを構築する。 - フィールド値の標準化: 変換 (
CASEステートメントなど) を使用して、データベースコードを明確なビジネス名に変換します (たとえば、注文ステータス 'O' を 'Open' に、'F' を 'Fulfilled' に変換)。 - フィルターでスコープを定義: メトリクスビューに完了した注文のみを含める必要がある場合は、ユーザーが誤って不完全なデータを含めないように、メトリクスビューでそのフィルターを定義します。
- 明確な命名を使用する : メトリクス名はビジネスユーザーにとって認識可能であるべきです (例えば、
cltv_agg_measureではなく「Customer Lifetime Value」)。 - 個別の時間フィールド : 詳細な時間フィールド (「Order Date」など) と切り捨てられた時間フィールド (「Order Month」や「Order Week」など) を含めて、詳細レベルとトレンド分析の両方を可能にします。