Microsoft Fabricでグラフ スキーマを設計する

グラフ スキーマは、ノードの種類、エッジの種類、およびグラフの構造を定義するプロパティのコレクションです。 適切に設計されたグラフ スキーマを使用すると、データのクエリ、保守、拡張が容易になります。 この記事では、レイクハウス内の表形式データを、Microsoft Fabricの有効なラベル付きプロパティ グラフに変換するためのベスト プラクティスについて説明します。

グラフ モデル エディターでモデリングを開始する前に、次のガイドラインを使用してください。 ノードとエッジを作成する手順については、 グラフのチュートリアルを参照してください。 この記事の例では、 Adventure Works サンプル データセットを使用します。

Important

現在、Graph ではスキーマの進化はサポートされていません。 グラフ モデルを作成してそのデータを読み込んだ後、ノードの種類、エッジの種類、プロパティの追加や削除などの構造的な変更では、更新された構造に対してクエリを実行する前にすべてのデータを再読み込みする必要があります。 データを再読み込みするには、上部のリボンで [保存] を選択します。 このデータの再読み込みプロセスには時間がかかり、容量が消費されるため、モデリングを開始する前にスキーマを十分に計画してください。

前提条件

ノードの種類とエッジの種類について

スキーマを設計する前に、次の主要な概念を理解してください。

ノードの種類は、顧客、製品、注文など、グラフ内のエンティティの種類を定義します。 構成は次のとおりです。

  • ノード ラベル。ノードのこのカテゴリを識別する名前です。 たとえば、「 Customer 」のように入力します。 クエリでラベルを使用して、この種類のノードを参照します。
  • ソース テーブル。ノード タイプのソース データを提供する lakehouse テーブルです。 たとえば、 adventureworks_customers テーブルです。
  • 各ノードを一意に識別する キー 列。 たとえば、「 CustomerID_K 」のように入力します。
  • プロパティ。各ノードに属性として追加できるテーブルの列です。 たとえば、 FirstNameLastNameEmailAddressなどです。

ノードは、ノード タイプの個々のインスタンス (ソース テーブル内の 1 行) です。 たとえば、 adventureworks_customers の各行は Customer ノードになります。

エッジ タイプは、2 つのノード タイプ間のリレーションシップの種類を定義します。 構成は次のとおりです。

  • エッジ ラベル。このリレーションシップ のカテゴリを識別する名前です。 たとえば、「 purchases 」のように入力します。
  • 配信元ノードとターゲット ノード間のリレーションシップ データを含むソース テーブル。 たとえば、 adventureworks_orders テーブルです。
  • 原点ノード タイプと、エッジが接続するターゲット ノード タイプ。 たとえば、原点として Customer し、ターゲットとして Order します。

エッジとは、2 つの特定のノードを接続するソース テーブル内の 1 つの行である、エッジ タイプの個々のインスタンスです。

グラフ モデル エディターの [ノードの 追加] ボタンと [エッジの追加] ボタンは、個々のノードやエッジではなく、ノードタイプとエッジタイプを作成します。

エンティティとリレーションシップを識別する

まず、データ内の エンティティ (モノ) と リレーションシップ (接続) を識別します。 エンティティはノード 型になります。 エンティティ間の接続はエッジタイプとなります。

ソース テーブルについて次の質問をします。

  • 主なエンティティは何ですか? 実際の状況を表す行は、ノードタイプの候補です。 たとえば、顧客、製品、注文、従業員などです。
  • これらのエンティティは互いにどのように関連していますか? 別のテーブル (外部キー) の行を参照する列は、エッジの種類を提案します。 たとえば、CustomerID_FK テーブル内のordersは、customers テーブルを指しており、purchases エッジのモデリングを提案します。
  • 埋め込みエンティティはありますか? テーブル内の列は、独自のノード型に抽出する価値のある個別のエンティティを表している可能性があります。 例については、「 ノードタイプの選択」を参照してください。 詳細なチュートリアルについては、「 1 つのソース テーブルから複数のノードとエッジの種類を追加する」を参照してください。

ノードの種類を選択する

個別にクエリまたは走査する必要があるエンティティごとにノードの種類を作成します。 次のガイドラインを使用します。

エンティティを ノード型 にする場合... このプロパティは、次の場合に プロパティ として保持します。...
通り抜けるかそこに到達する必要があります。 これはトラバースするのではなく、読むためだけの説明メタデータです。
複数のエンティティがリレーションシップを共有します。 これは、それが属するエンティティに固有です。
照合またはグループ化するには、クエリで直接行う必要があります。 フィルター処理は、別のエンティティのプロパティとしてのみ行います。

例: Adventure Works データセットで、 Countryemployees テーブルの列として開始されます。 "どの従業員が同じ国に住んでいるか" または "従業員が最も多い国" をクエリする必要がある場合は、 Country を独自のノード タイプに抽出します。 従業員の国のみをラベルとして表示する必要がある場合は、プロパティのままにします。

キー列の選択

すべてのノード タイプには、各ノードを一意に識別するキー列 (または複合キー) が必要です。 キーは慎重に選択してください。

  • ソース テーブルの既存の一意識別子を使用してください。 たとえば、CustomerID_K または ProductID_K です。
  • 自然キーが存在しない限り、ビジネス上の意味がない代理キーは避けてください。 たとえば、自動インクリメント行番号よりも CustomerID を優先します。
  • 1 つの列で一意性が保証されない場合は、複合キーを使用します。 たとえば、 ProductVersion ノードでは、キーとして ProductIDVersionNumber の両方が必要な場合があります。
  • キー列とエッジ マッピングで使用される外部キー列の間でデータ型を一致させます。 型が一致しない場合、エッジの作成エラーが発生します。

ヒント

ノード キー制約を定義して、クエリ エンジンがキー プロパティに対して直接参照を実行できるようにします。 この最適化により、キーごとに特定のノードを検索するクエリが高速化されます。

ノードのプロパティを追加する

ノード の種類を作成するときに、ノードの種類にプロパティとして含めるソース テーブルのプロパティ、特に基になるソース テーブルに OneLake セキュリティ アクセス規則が適用されているプロパティを選択します。

[+ プロパティの追加] ボタンを使用して、ノードの作成時に プロパティを追加 します。 または、グラフ モデル エディターでノード タイプをダブルクリックしてノード編集ダイアログを開き、[ 定義の編集] を選択して、既存のノードにプロパティを追加します。 [ プロパティの追加] を選択し、ソース テーブルから列を選択します。

テーブル内のすべての列をプロパティとして追加したくない場合があります。 過剰なプロパティを使用すると、ストレージが増加し、クエリが遅くなり、グラフの保守が困難になります。 このような理由から、クエリや分析に必要のないプロパティを追加しないでください。

ノードの種類ごとに、次のプロパティのみを保持します。

  • ノードの一意性 (キー列) に必要
  • クエリの WHERE フィルターまたは RETURN プロジェクションで使用されます
  • ダウンストリーム分析または視覚化に必要

プロパティ数がクエリのパフォーマンスに与える影響の詳細については、「 必要なプロパティのみを返す」を参照してください。

データ型の選択

各プロパティの最も具体的なデータ型を選択します。 適切な種類により、ストレージ効率とクエリパフォーマンスの両方が向上します。

  • 数値識別子とカウントには、 INT または UINT64 を使用します。 数値比較は、文字列比較よりも高速です。
  • 文字列形式の日付ではなく、タイムスタンプに ZONED DATETIME を使用します。
  • BOOLEAN"yes"などの文字列値の代わりに、true/false フラグに"no"を使用します。

サポートされている型の完全な一覧については、「 現在の制限事項 - データ型」を参照してください。

エッジの種類を選択する

エッジタイプは、ノードタイプ間のリレーションシップを定義します。 各エッジ タイプは、ソース テーブルを介して配信元ノード タイプをターゲット ノード タイプに接続します。

次のガイドラインに従ってください。

  • 動詞または動詞句として読み取る説明ラベルを使用します。 たとえば、 purchasessellslivesInbelongsToなどです。 適切な名前のエッジを使用すると、クエリの読み取りが容易になります。
  • 方向を慎重に検討してください。 グラフのエッジは有向です。 実際の関係を最もよく表す方向を選択します。 たとえば、 Customer --purchases--->Order は、 Order --purchasedBy-->Customer よりも自然に読み取ります。
  • 異なるノード タイプ ペアを接続するエッジ タイプに個別の名前を付けます。 "従業員が注文を販売する" と "顧客の発注書" の両方が Orderに接続する場合は、同じラベルの両方を指定するのではなく、 sellspurchases に名前を付けます。 詳細については、 エッジ作成の制限事項を参照してください。

エッジの種類にプロパティを追加する

ノードと同様に、エッジの種類はプロパティなしで開始されます。 必要に応じて、いずれかのエンドポイントではなく、データがリレーションシップ自体を記述するときにプロパティを追加できます。 エッジ プロパティは、リレーションシップ自体に関するデータをフィルター処理、集計、または返す必要がある GQL クエリを記述する場合に最も便利です。

プロパティを追加するには、グラフ モデル エディターでエッジタイプをダブルクリックしてエッジ編集ダイアログを開き、[ 定義の編集] を選択します。 [ プロパティの追加] を選択し、ソース テーブルから列を選択します。

エッジ プロパティを追加する場合: 2 つのノード間の接続に関して、列が "どのくらいの量"、"いつ"、または "どのような方法で?" と答える場合、列はどちらのノードにも属していませんが、エッジに属します。

例:Adventure Works データセットでは、contains エッジは、adventureworks_orders テーブルを介してOrderProductに接続します。 OrderQtyUnitPriceLineTotalなどの列は、関係 (特定の注文に含まれる製品の数) を価格で表します。 OrderDateShipDateなどの列は、順序自体を記述し、エッジではなく、Order ノード タイプに属します。

Important

エッジのソース テーブルには、値とデータ型の元とターゲットの両方のノード型のキー列に一致する列が含まれている必要があります。 ノード タイプの作成に使用するテーブルは、この要件を満たしている場合にエッジ ソース テーブルとしても機能します。

表形式からグラフへの一般的なパターン

次の表は、一般的な表形式データ構造がグラフ要素にどのように変換されるかをまとめたものです。

表形式の構造 グラフの結果
一対多: 親テーブル + 外部キーを持つ子テーブル エッジ タイプによって接続された 2 つのノード タイプ。 Customer -- 購入-->Order
多対多: 2 つのテーブルをリンクするジャンクション テーブル 2 つのノード タイプ間のエッジ タイプ。 Vendor -- 生成する-->Product
埋め込みエンティティ: 共有エンティティを表す列 抽出されたノードの種類とエッジ。 Employee -- livesIn-->Country
階層: 親子テーブルのチェーン 各レベルのエッジによってリンクされたノード タイプ。 Product -- isOfType-->Subcategory --belongsTo-->Category

埋め込みエンティティ パターンの詳細なチュートリアルについては、「 1 つのソース テーブルから複数のノードとエッジの種類を追加する」を参照してください。

グラフ スキーマを変更する

グラフはスキーマの進化をサポートしていません。 グラフ モデルを保存すると、ノードタイプ、エッジタイプ、およびそれらのプロパティの構造が固定されます。 ノード タイプへのプロパティの追加、エッジの種類の削除、キー列の変更など、構造的な変更を行うには、新しいグラフ モデルを作成してデータを再読み込みする必要があります。

グラフ スキーマを変更するには:

  1. ワークスペースで、同じレイクハウスに接続する新しいグラフ項目を作成します。
  2. グラフ モデル エディターで、新しいプロパティや変更されたプロパティを含め、必要なノードの種類とエッジの種類を追加します。
  3. キー列とエッジ マッピングを構成します。 キー列と外部キー列の間でデータ型が一致していることを確認します。
  4. [保存] を選択してデータを取り込み、新しいグラフを作成します。
  5. 新しいグラフを指すクエリセットを更新します。
  6. 新しいグラフが期待どおりに動作することを確認した後、不要な場合は元のグラフ項目を削除します。