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_custkeyとo_custkeyは物理ベーステーブルの列です。テーブル・エイリアス参照: リレーションシップや式でテーブルを参照する場合は、定義されたエイリアスを使用する必要があります。
例えば、テーブル・エイリアス
orders AS snowflake_sample_data.tpch.orders_tableを定義する場合、メトリクスの定義ではテーブル・エイリアスordersを使用する必要があります(orders_tableは使用しないでください)。論理テーブルにエイリアスを指定しない場合、論理テーブル名を式で使用する必要があります。
リレーションシップの検証ルール¶
セマンティックビューのリレーションシップには以下のルールが適用されます。
Many-to-one relationships and one-to-one relationships: Relationships work like foreign key constraints.
Suppose that the logical table
table_1identifiescol_1as a primary key:TABLES ( table_1 AS my_table_1 PRIMARY KEY (col_1) ...
When you define a relationship as
table_2 (col_2) REFERENCES table_1 (col_1),col_1must be a primary key, andcol_2must serve as a foreign key:If multiple rows in
table_2use the same value incol_2, you're creating a many-to-one relationship fromtable_2totable_1.For example,
orders (o_custkey) REFERENCES customers (c_custkey)creates a many-to-one relationship fromorderstocustomers(many orders can belong to one customer with the keyc_custkey).If each row in
table_2has a unique value incol_2, you're creating a one-to-one relationship fromtable_2totable_1.For example,
customer_details_extended (e_custkey) REFERENCES customer_details (c_custkey)creates a one-to-one relationship fromcustomer_details_extendedtocustomer_details(one row of extended details for a customer belongs to one row of customer details with the keyc_custkey).
Validations performed on one-to-one relationships:
Row-level expressions can refer to other row-level expressions at the same (or lower) granularity.
For example,
customer_detailsandcustomer_details_extendedhave a one-to-one relationship, where one row incustomer_detailsis related to one row incustomer_details_extended. A row-level expression on each of these tables refers to one specific customer. Each can refer directly to the other in row-level expressions because the row-level expressions are at the same granularity.As a corollary, a row-level expression on
customer_detailscannot reference a metric or aggregation of a row-level expression oncustomer_details_extended(and vice versa).Aggregate-level expressions must refer to row-level expressions at the same granularity using a single aggregate.
For example, aggregate-level expressions on
customer_detailsorcustomer_details_extendedmust use a single aggregate when referencing the other entity. In addition, metrics oncustomer_detailsandcustomer_details_extendedshould refer to other metrics on the two entities directly, without any aggregation.
These rules apply whether the relationship between the entities is defined as
customer_details REFERENCES customer_details_extendedorcustomer_details_extended REFERENCES customer_details.推移的リレーションシップ: Snowflakeは間接的なリレーションシップを自動的に導き出します。
たとえば、
line_itemsとordersの間のリレーションシップと、ordersとcustomerの間のリレーションシップを定義した場合、Snowflake はline_itemsとcustomerの間のリレーションシップも理解します。Note that one-to-one relationships respect transitivity when interacting with other one-to-one and many-to-one relationships:
If logical tables
customersandcustomer_detailshave a one-to-one relationship and logical tablescustomer_detailsandcustomer_details_extendedhave a one-to-one relationship, logical tablescustomersandcustomer_details_extendedare automatically inferred to have a one-to-one relationship and are treated as such during validation.If logical tables
customersandcustomer_detailshave a one-to-one relationship and logical tablescustomer_detailsandregionshave a many-to-one relationship,customersis inferred to be transitively many-to-one toregions, which givescustomersa higher granularity thanregionsduring expression validation.
循環的なリレーションシップの禁止: たとえ他動パスであっても、循環的なリレーションシップを定義することはできません。
たとえば、
ordersからcustomerへのリレーションシップと、customerからordersへのリレーションシップを定義することはできません。自己参照の禁止: 現在、テーブルが自分自身をリファレンスすることはできません (従業員が他の従業員をマネージャーとして参照できる従業員マネージャーの階層のように)。
マルチパスのリレーションシップの制限: 2つのテーブル間に複数のリレーションシップを定義できますが、制限があります。
例えば、
line_itemsがorder_keyと別の列の両方を通してordersに関連している場合、これらのテーブルはお互いの意味式を参照することはできません。注釈
2つのテーブルの結合に使用できるパスが複数ある場合は、パスごとに個別の論理テーブルと関係を定義する必要があります。詳細については、 2つのテーブルを結合するパスごとに異なる論理テーブルを定義する をご参照ください。
式の検証ルール¶
以下のルールは、ファクト、ディメンジョン、およびメトリクスの意味式に適用されます。
式に関する一般規則¶
意味式全般には以下のルールが適用されます。
式のタイプ: ディメンジョンとファクトは行レベル式 (未集約)、メトリクスは集約レベル式です。
例えば、
customer_nameはディメンジョン(行レベル)ですが、order_average_valueはメトリクス(集約レベル)です。テーブルの関連付け: すべての意味式はテーブルに関連付けられなければなりません。
例えば、
customer_nameはcustomer.customer_nameとして、order_average_valueはorders.order_average_valueとして定義されなければなりません。同じテーブルのリファレンス: リファレンス式は、修飾名または非修飾名を使用して、ベーステーブル列または同じ論理テーブル上の他の式を参照できます。
例えば、
ordersテーブルで、orders.shipping_monthを次のように定義します。MONTH(o_shipdate)(修飾されていない列名を使用)MONTH(orders.o_shipdate)(修飾名を使用)
テーブル間の制限: 式は、他のテーブルのベーステーブル列や、リレーションシップのない論理テーブルの式を参照することはできません。
例えば、
customer.customer_nameは、両者の間にリレーションシップがない限り、ordersテーブルの式を直接リファレンスすることはできません。テーブルをまたいでデータを扱うには、次のことが必要です。論理テーブル間のリレーションシップを定義します(たとえば、
c_custkeyを通したcustomerとorders)。ソース・テーブルのファクトを定義します (例えば、
orders.total_value)。接続論理表からこれらの式を参照します(例えば、
customer.order_valueはorders.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と直接定義することができます。同じ粒度またはそれ以下の粒度: 行レベル式は、同じかそれ以下の粒度の他の行レベル式を直接参照することができます。
例えば、
customerはordersよりも粒度が小さいので、orders.order_detailsはcustomer.customer_nameをリファレンスすることができます(一人の顧客が多くの注文を持つことができます)。より高い粒度のリファレンス: より高い粒度で行レベル式を参照する場合、行レベル式は集約を使用する必要があります。
例えば、
ordersはcustomerよりも粒度が高いので、customer.total_ordersはCOUNT(orders.o_orderkey)を使わなければなりません(一人の顧客が多くの注文を持つことができます)。集約リファレンス:
orders.order_typeのようなディメンジョンは、orders.order_average_valueのようなメトリクスを参照できませんが、customerはオーダーよりも粒度が低いため、customer.customer_segmentはorders.order_average_valueを参照できます。
集約レベル式(メトリクス)のルール¶
以下のルールは、メトリクスの集約レベル式に適用されます。
基本的な集約: メトリクスは集約関数を使用しなければなりません。
例えば、
orders.order_average_valueはAVG(orders.o_totalprice)を使わなければなりません。同等以下の粒度: 同等以下の粒度で行レベル式をリファレンスする場合、メトリクスは単一の集約を使用しなければなりません。
例えば、
line_itemsはオーダーより粒度が低いので、orders.total_valueはSUM(line_items.discounted_price)を使うことができます。より高い粒度のリファレンス: より高い粒度で行レベルの式をリファレンスする場合、メトリクスはネストされた集約を使用する必要があります。
例えば、
ordersはcustomerよりも粒度が高いので、customer.average_order_valueはAVG(SUM(orders.o_totalprice))を使わなければなりません。他の集約リファレンス: メトリクスは、集約することなく、同じ粒度またはそれ以下の粒度の他のメトリクスを直接参照できます。
例えば、
orders.profit_marginは、追加集約なしでorders.total_revenue / orders.total_costと定義できます。ただし、より高い粒度のメトリクスをリファレンスする場合は、集計が必要です。
ウィンドウ関数メトリックのルール¶
これらのルールは :ref:`ウィンドウ関数メトリック <label-semantic_views_querying_window>`に適用されます。
ウィンドウ関数メトリックは、行レベルの計算(ファクトとディメンション)では使用できません。
ウィンドウ関数メトリックは、他のメトリックの定義では使用できません。