Snowflakeによるセマンティックビューの検証方法

Snowflakeは、セマンティックビューを定義する際に、一連の検証ルールに準拠しているかどうかを検証します。これらのルールは、あなたのセマンティックモデルが整形式であり、正しく機能することを保証します。

これらのルールについては、次のセクションで説明します。

一般的な検証ルール

以下のルールはセマンティックビュー全般に適用されます。

  • 必須要素: セマンティック・ビューでは、少なくとも 1 つのディメンジョンまたはメトリクスを定義する必要があります。

    例えば、 TPC-H セマンティックビューは、少なくとも1つのディメンジョン(customer_name のような)またはメトリクス(order_average_value のような)が必要です。

  • プライマリキーと外部キー: プライマリキーおよび外部キーの定義では、物理的なベーステーブル列、またはベーステーブル列を直接参照する論理テーブルで定義された式を使用する必要があります (例えば、 t1.fact AS t1.col)。

    たとえば、 TPC-H スキーマでは、 customer テーブルのプライマリキーとして c_custkey を、 orders テーブルの外部キーとして o_custkey を使用できます。 c_custkeyo_custkey は物理ベーステーブルの列です。

  • テーブル・エイリアス参照: リレーションシップや式でテーブルを参照する場合は、定義されたエイリアスを使用する必要があります。

    例えば、テーブル・エイリアス orders AS snowflake_sample_data.tpch.orders_table を定義する場合、メトリクスの定義ではテーブル・エイリアス orders を使用する必要があります(orders_table は使用しないでください)。

    論理テーブルにエイリアスを指定しない場合、論理テーブル名を式で使用する必要があります。

リレーションシップの検証ルール

セマンティックビューのリレーションシップには以下のルールが適用されます。

  • 多対一のリレーションシップ: リレーションシップは外部キー制約のように機能します。

    たとえば、 orders (o_custkey) REFERENCES customers (c_custkey) というリレーションシップを定義すると、 orders から customers への多対一のリレーションシップが作成されます (多くの注文が 1 人の顧客に属する可能性があります)。 c_custkey はプライマリキーでなければなりません。

  • 推移的リレーションシップ: Snowflakeは間接的なリレーションシップを自動的に導き出します。

    たとえば、 line_itemsorders の間のリレーションシップと、 orderscustomer の間のリレーションシップを定義した場合、Snowflake は line_itemscustomer の間のリレーションシップも理解します。

  • 循環的なリレーションシップの禁止: たとえ他動パスであっても、循環的なリレーションシップを定義することはできません。

    たとえば、 orders から customer へのリレーションシップと、 customer から orders へのリレーションシップを定義することはできません。

  • 自己参照の禁止: 現在、テーブルが自分自身をリファレンスすることはできません (従業員が他の従業員をマネージャーとして参照できる従業員マネージャーの階層のように)。

  • マルチパスのリレーションシップの制限: 2つのテーブル間に複数のリレーションシップを定義できますが、制限があります。

    例えば、 line_itemsorder_key と別の列の両方を通して orders に関連している場合、これらのテーブルはお互いの意味式を参照することはできません。

  • 一対一のリレーションシップの制約: 一対一のリレーションシップには制限があります。

    例えば、リレーションシップ orders(id) REFERENCES order_summary を定義したとします。 id はプライマリキーであるか、 orders に一意な値を持ちます。 order_summaryorders の意味式を参照することはできませんが、 ordersorder_summary のセマンティック式を参照することができます。

式の検証ルール

以下のルールは、ファクト、ディメンジョン、およびメトリクスの意味式に適用されます。

式に関する一般規則

意味式全般には以下のルールが適用されます。

  • 式のタイプ: ディメンジョンとファクトは行レベル式 (未集約)、メトリクスは集約レベル式です。

    例えば、 customer_name はディメンジョン(行レベル)ですが、 order_average_value はメトリクス(集約レベル)です。

  • テーブルの関連付け: すべての意味式はテーブルに関連付けられなければなりません。

    例えば、 customer_namecustomer.customer_name として、 order_average_valueorders.order_average_value として定義されなければなりません。

  • 同じテーブルのリファレンス: リファレンス式は、修飾名または非修飾名を使用して、ベーステーブル列または同じ論理テーブル上の他の式を参照できます。

    例えば、 orders テーブルで、 orders.shipping_month を次のように定義します。

    • MONTH(o_shipdate) (修飾されていない列名を使用)

    • MONTH(orders.o_shipdate) (修飾名を使用)

  • テーブル間の制限: 式は、他のテーブルのベーステーブル列や、リレーションシップのない論理テーブルの式を参照することはできません。

    例えば、 customer.customer_name は、両者の間にリレーションシップがない限り、 orders テーブルの式を直接リファレンスすることはできません。テーブルをまたいでデータを扱うには、次のことが必要です。

    1. 論理テーブル間のリレーションシップを定義します(たとえば、 c_custkey を通した customerorders)。

    2. ソース・テーブルのファクトを定義します (例えば、 orders.total_value)。

    3. 接続論理表からこれらの式を参照します(例えば、 customer.order_valueorders.total_value を参照できます)。

  • 名前解決: 意味式と列が同じ名前の場合、その名前へのリファレンスは意味式に解決されます。

    例えば、 region ディメンジョンを定義し、 region 列もある場合、式の region は列ではなくディメンジョンに解決されます。例外は、式の定義で同じ名前を参照している場合です(例えば、 customer.c_name AS customers.c_name)。リファレンスは、定義式そのものではなく、列に解決されます。

  • 式のリファレンス・サイクル: 式間の循環リファレンスは作成できません。

    例えば、 orders.customer_value に基づいて customer.total_value を定義し、 customer.total_value に基づいて orders.customer_value を定義することはできません。

  • テーブル参照のサイクル: 式定義で論理テーブル間の循環リファレンスを作成することはできません。

    たとえば、 orders.customer_value に基づいて customer.total_value を定義し、 customer.c_custkey. に基づいて orders.customer_count を定義することはできません。

  • 関数の使用: ディメンジョンでは YEAR* / DAY* / WEEK* / MONTH / QUARTER のようなスカラー関数を使用できますが、テーブル関数は使用できません。ウィンドウ関数は、ディメンジョンとファクトでは使用できますが、メトリクスでは使用できません。

行レベル式 (ディメンジョンおよびファクト) のルール

以下のルールは、ディメンジョンおよびファクトの行レベル式に適用されます。

  • 同じテーブルのリファレンス: 行レベル式は、そのテーブルの列を直接参照することができます。

    例えば、 customers.customer_name は、 customers.c_name と直接定義することができます。

  • 同じ粒度またはそれ以下の粒度: 行レベル式は、同じかそれ以下の粒度の他の行レベル式を直接参照することができます。

    例えば、 customerorders よりも粒度が小さいので、 orders.order_detailscustomer.customer_name をリファレンスすることができます(一人の顧客が多くの注文を持つことができます)。

  • より高い粒度のリファレンス: より高い粒度で行レベル式を参照する場合、行レベル式は集約を使用する必要があります。

    例えば、 orderscustomer よりも粒度が高いので、 customer.total_ordersCOUNT(orders.o_orderkey) を使わなければなりません(一人の顧客が多くの注文を持つことができます)。

  • 集約リファレンス: orders.order_type のようなディメンジョンは、 orders.order_average_value のようなメトリクスを参照できませんが、 customer はオーダーよりも粒度が低いため、 customer.customer_segmentorders.order_average_value を参照できます。

集約レベル式(メトリクス)のルール

以下のルールは、メトリクスの集約レベル式に適用されます。

  • 基本的な集約: メトリクスは集約関数を使用しなければなりません。

    例えば、 orders.order_average_valueAVG(orders.o_totalprice) を使わなければなりません。

  • 同等以下の粒度: 同等以下の粒度で行レベル式をリファレンスする場合、メトリクスは単一の集約を使用しなければなりません。

    例えば、 line_items はオーダーより粒度が低いので、 orders.total_valueSUM(line_items.discounted_price) を使うことができます。

  • より高い粒度のリファレンス: より高い粒度で行レベルの式をリファレンスする場合、メトリクスはネストされた集約を使用する必要があります。

    例えば、 orderscustomer よりも粒度が高いので、 customer.average_order_valueAVG(SUM(orders.o_totalprice)) を使わなければなりません。

  • 他の集約リファレンス: メトリクスは、集約することなく、同じ粒度またはそれ以下の粒度の他のメトリクスを直接参照できます。

    例えば、 orders.profit_margin は、追加集約なしで orders.total_revenue / orders.total_cost と定義できます。ただし、より高い粒度のメトリクスをリファレンスする場合は、集計が必要です。