Spanner Graph を使用すると、接続されたデータを、情報をノードとエッジのネットワークで表すプロパティ グラフとしてモデル化できます。ノードはエンティティを表し、エッジはノード間の接続を表します。ノードとエッジにはラベルが含まれており、このラベルによってノードとエッジがセットに分類されます。ノードとエッジには、Key-Value ペア形式のプロパティも含まれます。
Spanner Graph のスキーマを定義するには、入力テーブルの行をグラフのノードとエッジにマッピングします。ノードとエッジのラベルとプロパティをカスタマイズし、スキーマの変更がグラフの依存関係にどのように影響するかを理解します。グラフをより柔軟に定義するため、スキーマレス データを管理することもできます。
Spanner Graph の詳細については、Spanner Graph の概要をご覧ください。
プロパティ グラフのデータモデルを理解する
プロパティ グラフを使用すると、接続されたデータをモデル化できます。グラフには、情報がノードとエッジのネットワークとして表示されます。ノードは、データ ランドスケープ内のエンティティ(顧客、商品、場所など)を表します。エッジはノード間の接続を示し、ソースノードと宛先ノード間の関係(購入済み、フォロー中、配置済みなど)をキャプチャします。
ノードとエッジの両方に、次の情報を含めることができます。
- ラベル。ノードとエッジをセット(都市など)に分類します。
- プロパティ(Key-Value ペア)。たとえば、人口などです。
図 1 の例は、財務活動をモデル化するグラフを設計する方法を示しています。このグラフには、ノードとしてモデル化された次のタイプのエンティティが含まれています。
- Person: 金融取引に関与する個人を表します。
- Account: 取引に使用される銀行口座を表します。
これらのエンティティは、次の有向エッジで表されるさまざまなタイプの関係で接続されています。
- Owns: 1 人につき 1 つ以上のアカウントを所有しています。
- Transfers: 資金はある口座から別の口座に移動します。
各有向エッジは、ソースノードから宛先ノードへの一方向の関係を表します。たとえば、Transfers エッジは、ソース Account を宛先 Account に接続し、資金の流れを示します。
 
 
図 1: 複数のノードと有向エッジを含むグラフの例。
ノードとエッジには、プロパティに追加情報が含まれています。各プロパティには名前と値が含まれます。
- Person ノードには、次のプロパティが含まれます。- name(- STRING)
- id(- INT64)
 
- Transfers エッジには、次のプロパティが含まれます。- amount(FLOAT64)
 
有向エッジと無向エッジ
このグラフの例では、エンティティ間の関係の特定の方向を示す有向エッジが使用されています。ただし、ソーシャル ネットワークの「友だち」関係のような関係は無向であり、明確な始点も終点もない相互接続を表します。この場合、無向エッジを 2 つの有向エッジ(各方向に 1 つのエッジ)としてモデル化できます。
Spanner Graph スキーマの設計
Spanner Graph では、CREATE PROPERTY GRAPH ステートメントを使用してテーブルからグラフを作成できます。グラフを作成するテーブルのことを「入力テーブル」と呼びます。このアプローチでは、SQL:2023 標準に含まれる SQL/PGQ(Property Graph Queries)を使用します。
プロパティ グラフのノードを定義する
ノードを定義するには、NODE TABLES 句にノードの定義を追加します。最もシンプルなノード定義の形式では、入力テーブル名のみを含めます。これにより、入力テーブルの行がグラフのノードにマッピングされます。
次の例では、NODE TABLES 句を使用して、FinGraph プロパティ グラフに Account ノードを定義しています。ノード定義には入力テーブル Account が含まれています。
-- First, create an Account table.
CREATE TABLE Account (
  id           INT64 NOT NULL,
  create_time  TIMESTAMP,
) PRIMARY KEY (id);
-- Next, use the Account table as input table of Account node definition.
CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Account
  );
デフォルトのラベルとプロパティ
デフォルトでは、すべてのノードが入力テーブル名をラベルとして持ち、入力テーブルのすべての列がノード プロパティとして公開されます。
上の例では、次のようになります。
- 各アカウント ノードは、Accountというラベルを持ちます。
- 各アカウント ノードには、Accountテーブルの列から作成された[id, create_time]というプロパティが含まれます。
要素キー
ノード定義では、グラフノードを一意に識別する要素キーも定義します。
- デフォルトでは、要素キーは入力テーブルの主キーです。
- KEY句を使用して、要素キーを明示的に定義できます。
- 一意のインデックス制約が設定されている列を要素キーとして使用できます。
次の例では、Account ノードと Person ノードを定義しています。
- Accountノードの要素キーは- Accountテーブルの主キーになります(デフォルトの動作)。
- それに対して、Personノードの要素キーは、KEY句を使用して明示的にidに設定されています。
CREATE TABLE Person (
  id           INT64 NOT NULL,
  name         STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
  id           INT64 NOT NULL,
  create_time  TIMESTAMP,
) PRIMARY KEY (id);
CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person KEY (id),
    Account
  );
入力テーブルの行をグラフのノードにマッピングする
- 要素キーが null 以外の各行は、要素キーで識別されるグラフ内の一意のノードにマッピングされます。
- 要素キーが null の行は無視されます。
プロパティ グラフのエッジを定義する
エッジを定義するには、EDGE TABLES 句にエッジ定義を追加します。最もシンプルなエッジ定義の形式では、入力テーブル名のみを含めます。これにより、入力テーブルの行がグラフのエッジにマッピングされます。
- エッジのデフォルトのラベルとプロパティは、ノードと同じ方法で定義されます。 
- 各エッジの要素キーは、ノードと同じ方法で定義されます。 
ソースノードと宛先ノードの参照
次の例では、次の設定でプロパティ グラフ FinGraph を作成します。
- Personノードと- Accountノード
- PersonOwnAccountエッジ
CREATE TABLE Person (
 id            INT64 NOT NULL,
 name          STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
 id            INT64 NOT NULL,
 create_time   TIMESTAMP,
) PRIMARY KEY (id);
CREATE TABLE PersonOwnAccount (
 id            INT64 NOT NULL,
 account_id    INT64 NOT NULL,
 create_time   TIMESTAMP,
 FOREIGN KEY (account_id) REFERENCES Account (id)
) PRIMARY KEY (id, account_id),
  INTERLEAVE IN PARENT Person;
CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person,
    Account
  )
  EDGE TABLES (
    PersonOwnAccount
      SOURCE KEY (id) REFERENCES Person (id)
      DESTINATION KEY (account_id) REFERENCES Account (id)
  );
エッジ定義では、SOURCE KEY、DESTINATION KEY、REFERENCES 句を使用して、ソースノードと宛先ノードの参照を定義します。次の例では、このコンセプトを示すために PersonOwnAccount のエッジ定義を使用しています。
EDGE TABLES (
  PersonOwnAccount
    SOURCE KEY (id) REFERENCES Person (id)
    DESTINATION KEY (account_id) REFERENCES Account (id)
)
各 PersonOwnAccount エッジは、Person(ソース)ノードを Account(宛先)ノードに接続します。
- エッジのソースノードは、idがエッジのidと同じであるPersonノードです。
- エッジの宛先ノードは、idがエッジのaccount_idと同じであるAccountノードです。
また、PersonOwnAccount エッジについては次のことが言えます。
- 要素キーは、PersonOwnAccountテーブルの主キー((id, account_id))です。
- 各エッジには、PersonOwnAccountテーブルの列と同じプロパティのセットがあります。
- 各エッジにはデフォルトの PersonOwnAccountラベルが付いています。
エッジ入力テーブルの行をグラフのエッジにマッピングする
- エッジ入力テーブルの各行(要素キーが null でない行)は通常、グラフ内の一意のエッジにマッピングされます。
- 1 行がグラフ内の 0 個以上のエッジに対応する場合があります。たとえば、ソースノード参照がソースノード テーブル内の 0 個以上のノードと一致する場合はそのようになります。
- 同じ入力テーブルを異なるノード定義またはエッジ定義で使用して、ノードまたはエッジの異なるセットを作成できます。詳細については、ノード入力テーブルとエッジ入力テーブルを統合するをご覧ください。
ラベルとプロパティをカスタマイズする
LABEL 句と PROPERTIES 句を使用して、ラベルとプロパティをカスタマイズできます。
次の例では、Person と Account の 2 つのノードを定義しています。
- Personノードは、- Customerラベルを使用して- addressプロパティを公開します。- addressプロパティは、入力テーブル- Personの- city列と- country列を参照する式- CONCAT(city, ", ", country),によって定義されています。
- Accountの場合、- Accountノードは- Accountラベルを使用して- idプロパティと- create_timeプロパティを公開します。
- Personと- Accountには、プロパティ [- id, name] を持つ- Entityラベルがあります。- Personの場合、- idプロパティと- nameプロパティは入力テーブルの列から取得されます。
- Accountの場合、- nameプロパティは入力テーブルの- nick_name列を参照します。
 
CREATE TABLE Person (
 id               INT64 NOT NULL,
 name             STRING(MAX),
 birthday         TIMESTAMP,
 country          STRING(MAX),
 city             STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
 id               INT64 NOT NULL,
 create_time      TIMESTAMP,
 is_blocked       BOOL,
 nick_name        STRING(MAX),
) PRIMARY KEY (id);
CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person KEY (id)
      LABEL Customer
        PROPERTIES (CONCAT(city, ", ", country) AS address)
      LABEL Entity PROPERTIES (id, name),
    Account KEY (id)
      LABEL Account PROPERTIES (id, create_time)
      LABEL Entity PROPERTIES (id, nick_name AS name)
  );
ラベルとプロパティの整合性
グラフでは、ラベルとプロパティはそれぞれの名前によって一意に識別されます。同じ名前のラベルとプロパティは、複数のノード定義またはエッジ定義で使用できます。ただし、同じ名前のラベルとプロパティについては、次のルールがあります。
- 同じ名前のプロパティは、同じ値の型を使用します。
- 同じ名前のラベルは、同じプロパティのリストを公開します。
上の例では、Entity ラベルは Person ノードと Account ノードの両方で定義されています。どちらの定義にも、同じ値の型を持つ同じプロパティ名のセット [id, name] が含まれています。
グラフと他のスキーマ オブジェクト間の依存関係
CREATE PROPERTY GRAPH によって作成されたグラフは、ノード定義とエッジ定義の入力テーブルや、プロパティによって参照されるテーブル列など、他のスキーマ オブジェクトに依存しています。Spanner Graph では、これらの依存関係のいずれかを破壊するスキーマの変更は許可されません。
次のステートメントは、FinGraph を Account テーブルと id 列および create_time 列に依存させます。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Account PROPERTIES (id, create_time)
  );
この例では、次のようなスキーマ変更は許可されません。
- Accountテーブルを削除することはできません。これを行うには、- Accountノード定義を削除する必要があります。詳細については、既存のノード定義またはエッジ定義を削除するをご覧ください。
- Accountテーブルから- create_time列を削除することはできません。これを行うには、- Accountノード定義から- create_timeプロパティを削除する必要があります。詳細については、既存のノード定義またはエッジ定義を更新するをご覧ください。
ただし、次のスキーマ変更は可能です。
- 他のスキーマ要件で許可されている場合、Accountテーブルとid列およびcreate_time列のスキーマを変更する。詳細については、スキーマの更新をご覧ください。
スキーマを可視化する
Spanner Graph クエリを実行すると、Spanner Studio にスキーマが可視化されます。詳細については、Spanner Graph の可視化を使用するをご覧ください。
スキーマレス データを管理する
Spanner Graph ではスキーマレス データの管理もサポートされており、より柔軟なグラフ定義が必要な場合に役立ちます。詳細については、Spanner Graph でスキーマレス データを管理するをご覧ください。