結構定義總覽

本文說明圖表結構定義的元件,以及如何建立和管理圖表結構定義。

圖形可讓您模擬連結的資料,將資訊表示為節點和邊的網路。圖表結構定義包含節點和邊緣,以及用於分類類型的標籤和描述屬性。如要定義圖形結構定義,請將輸入資料表的資料列對應至圖形節點和邊緣,並定義自訂標籤和屬性。如要進一步瞭解 BigQuery Graph,請參閱「BigQuery Graph 總覽」。

瞭解圖表資料模型

圖譜可讓您將連結的資料模擬為節點和邊緣的網路。節點代表資料中的實體,例如客戶、產品或位置。邊緣則代表這些節點之間的連結,可擷取購買、追蹤或位置等關係。

節點和邊緣可包含下列資訊:

  • 標籤:分類節點和邊緣類型。舉例來說,班上的學生可能會有 Student 標籤和 Person 標籤。如未明確定義節點或邊緣的標籤,BigQuery Graph 會使用輸入資料表名稱做為預設標籤。

  • 屬性:用於描述節點和邊緣。舉例來說,代表人物的節點可能會有值為 Alex 的 name 屬性,以及值為 1 的 id 屬性。

圖 1 範例說明如何設計圖表,為金融活動建立模型。這個圖表包含下列類型的實體,以節點表示:

  • Person:代表參與金融交易的個人。
  • 帳戶:代表用於交易的銀行帳戶。

這些實體透過不同類型的關係連結,並以有向邊表示:

  • 擁有:使用者擁有一或多個帳戶。
  • 轉帳:將款項從一個帳戶轉移到另一個帳戶。

每個有向邊都代表從來源節點流向目的地節點的單向關係。舉例來說,Transfers 邊緣會連結來源 Account 和目的地 Account,表示資金流向。

財務圖表的節點、邊緣、標籤和屬性。

圖 1.包含多個節點和有向邊的圖表範例。

節點和邊緣包含屬性中的其他資訊。

  • Person 節點包含下列屬性:

    • name (STRING)
    • id (INT64)
  • Transfers 邊緣包含以下屬性:

    • amount (FLOAT64)

有向和無向邊

有向邊緣表示實體之間關係的特定方向。例如,使用者擁有帳戶,但帳戶不擁有使用者。不過,有些關係 (例如社群網路中的朋友關係) 是「無向」,代表雙向連結。在這種情況下,您可以將無向邊建模為兩個有向邊,每個方向各一個邊。

設計結構定義

BigQuery Graph 可讓您使用 CREATE PROPERTY GRAPH 陳述式,從資料表建立圖表。用於建立圖表的資料表稱為「輸入資料表」。

定義節點

節點是由下列資料表或檢視表類型的資料列定義:

  • 標準資料表
  • 外部資料表
  • Apache Iceberg 代管資料表
  • Lakehouse Iceberg REST 目錄資料表
  • 檢視表 (包括授權檢視表)
  • 非增量 materialized view

如要定義節點,請在 NODE TABLES 子句中新增節點定義。節點定義的最簡單形式包含輸入資料表的名稱,以及主鍵。BigQuery Graph 會將輸入資料表的資料列對應至圖譜節點。

在以下範例中,您可以使用 NODE TABLES 子句,在 FinGraph 圖表中定義 Account 節點。節點定義包含輸入資料表 Account。

-- Create an Account table.
CREATE TABLE graph_db.Account (
  id           INT64 NOT NULL,
  create_time  TIMESTAMP,
  PRIMARY KEY (id) NOT ENFORCED
);

-- Use the Account table as the input table for the Account node definition.
CREATE PROPERTY GRAPH graph_db.FinGraph
  NODE TABLES (
    graph_db.Account
  );

根據預設,BigQuery 會使用資料表名稱做為標籤,並將輸入資料表的所有資料欄公開為屬性。

  • 每個帳戶節點都會使用 Account 標籤。
  • 每個帳戶節點都包含 Account 資料表資料欄中的 id 和 create_time 屬性。

元素鍵

節點定義也會定義元素鍵,這是一組可專門識別圖表節點的資料欄。根據預設,元素鍵是輸入資料表的主鍵。或者,您也可以使用 KEY 子句明確定義元素鍵。

以下範例定義了 Account 節點和 Person 節點。Account 節點會使用 Account 資料表的主鍵做為元素鍵。Person 節點會使用 KEY 子句,明確指定 id 欄做為元素索引鍵。

CREATE TABLE graph_db.Person (
  id           INT64 NOT NULL,
  name         STRING
);

CREATE TABLE graph_db.Account (
  id           INT64 NOT NULL,
  create_time  TIMESTAMP,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE PROPERTY GRAPH graph_db.FinGraph
  NODE TABLES (
    graph_db.Person KEY (id),
    graph_db.Account
  );
  • 每個含有非空值元素鍵的資料列,都會對應至圖表中由元素鍵識別的專屬節點。
  • 系統會忽略元素索引鍵為空值的資料列。

同一個輸入資料表可用於多個節點定義。在這種情況下,輸入資料表中的特定資料列會對應至每個節點定義的一個節點。

定義邊緣

邊緣是由下列資料表或檢視表類型的資料列定義:

  • 標準資料表
  • 外部資料表
  • Apache Iceberg 代管資料表
  • Lakehouse Iceberg REST 目錄資料表
  • 檢視表 (包括授權檢視表)
  • 非增量 materialized view

如要定義邊緣,請在 EDGE TABLES 子句中加入邊緣定義。最簡單的邊緣定義形式包含輸入資料表的名稱,並定義來源和目的地節點參照。BigQuery Graph 會使用這項定義,將輸入資料表中的資料列對應至圖譜邊緣。

根據預設,BigQuery 會使用資料表名稱做為標籤,並將輸入資料表的所有資料欄公開為屬性。

來源和目的地節點參照

邊緣定義會使用 SOURCE KEY、DESTINATION KEY 和 REFERENCES 子句,定義來源和目的地節點參照。您必須先定義來源和目的地節點,才能在邊緣定義中使用。

在以下範例中,您將建立名為 FinGraph 的圖表,其中包含下列元素:

  • Person 和 Account 節點
  • PersonOwnAccount 邊緣
CREATE TABLE graph_db.Person (
  id            INT64 NOT NULL,
  name          STRING,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE TABLE graph_db.Account (
  id            INT64 NOT NULL,
  create_time   TIMESTAMP,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE TABLE graph_db.PersonOwnAccount (
  id            INT64 NOT NULL,
  account_id    INT64 NOT NULL,
  create_time   TIMESTAMP,
  FOREIGN KEY (account_id) REFERENCES graph_db.Account (id) NOT ENFORCED,
  PRIMARY KEY (id, account_id) NOT ENFORCED
);

CREATE PROPERTY GRAPH graph_db.FinGraph
  NODE TABLES (
    graph_db.Person,
    graph_db.Account
  )
  EDGE TABLES (
    PersonOwnAccount
      SOURCE KEY (id) REFERENCES Person (id)
      DESTINATION KEY (account_id) REFERENCES Account (id)
  );

每個 PersonOwnAccount 邊緣都會將 Person (來源) 節點連結至 Account (目的地) 節點。

  • 邊緣的來源節點是 Person 節點,其中 id 屬性與邊緣 id 屬性相同。
  • 邊緣的目的地節點是 Account 節點,其中 id 屬性與邊緣 account_id 屬性相同。
  • 元素鍵是 PersonOwnAccount 資料表的主鍵,即 (id, account_id)。
  • 每個邊緣都有一組與 PersonOwnAccount 資料表中的資料欄相同的屬性。
  • 每個邊緣都有預設的 PersonOwnAccount 標籤。

將資料列對應至邊緣

邊緣輸入資料表中,元素索引鍵非空值的每一列,通常會對應至圖形中的單一邊緣。不過,如果來源或目的地節點參照與來源或目的地節點資料表中的零或多個節點相符,則邊緣輸入資料表中的資料列可能會在圖表中產生零或多個邊緣。

在同一個資料表中定義節點和邊緣

如果資料表的資料欄定義了與其他資料表的關係,您可以在單一資料表中定義節點及其傳入或傳出邊緣。這種做法可減少資料表數量、簡化資料管理作業,而且不必與獨立的邊資料表進行 join,因此可提升查詢效能。

舉例來說,如果下列 Account 資料表具有複合主鍵 (owner_id, account_id),則 owner_id 資料欄可以是參照 Person 資料表的外鍵。這種結構可讓 Account 資料表同時代表 Account 節點和來自 Person 節點的傳入邊緣。

CREATE TABLE graph_db.Person (
  id INT64 NOT NULL,
  PRIMARY KEY (id) NOT ENFORCED
);

-- Assume each account has exactly one owner.
CREATE TABLE graph_db.Account (
  owner_id INT64 NOT NULL,
  account_id INT64 NOT NULL,
  FOREIGN KEY (owner_id) REFERENCES graph_db.Person(id) NOT ENFORCED,
  PRIMARY KEY (owner_id, account_id) NOT ENFORCED
);

您可以使用 Account 資料表定義 Account 節點和其傳入的 Owns 邊緣。如以下 CREATE PROPERTY GRAPH 陳述式所示。在 EDGE TABLES 子句中,您將 Account 資料表命名為 Owns。這是因為圖表結構定義中的每個元素都必須有不重複的名稱。

CREATE PROPERTY GRAPH graph_db.FinGraph
  NODE TABLES (
    graph_db.Person,
    graph_db.Account
  )
  EDGE TABLES (
    graph_db.Account AS Owns
      SOURCE KEY (owner_id) REFERENCES Person
      DESTINATION KEY (owner_id, account_id) REFERENCES Account
  );

自訂標籤和屬性

您可以使用 LABEL 和 PROPERTIES 子句自訂標籤和屬性。

以下範例定義了具有自訂屬性的 Person 節點,以及具有多個標籤的 Account 節點:

CREATE TABLE graph_db.Person (
  id               INT64 NOT NULL,
  name             STRING,
  birthday         TIMESTAMP,
  country          STRING,
  city             STRING,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE TABLE graph_db.Account (
  id               INT64 NOT NULL,
  create_time      TIMESTAMP,
  is_blocked       BOOL,
  nick_name        STRING,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE PROPERTY GRAPH graph_db.FinGraph
  NODE TABLES (
    graph_db.Person KEY (id)
      LABEL Customer
      PROPERTIES (CONCAT(city, ", ", country) AS address)
      LABEL Entity PROPERTIES (id, name),
    graph_db.Account KEY (id)
      DEFAULT LABEL OPTIONS(description = 'A checking or savings account')
      PROPERTIES (id, create_time)
      LABEL Entity
      PROPERTIES (
        id,
        nick_name AS name OPTIONS(description = 'A user-defined account name',
                                  synonyms = ['friendly name', 'display name'],
                                  extensions = [('data_classification', 'user'), ('currency', 'USD')])
      )
  );
  • Person 節點會使用 Customer 標籤公開 address 屬性。address 屬性是由運算式 CONCAT(city, ", ", country), 定義,該運算式參照輸入資料表 Person 的 city 和 country 資料欄。

  • Account 節點會使用 Account 標籤,公開 id 和 create_time 屬性。

Person 和 Account 節點都有 Entity 標籤,且具有 id 和 name 屬性。

  • 在 Person 節點中,id 和 name 屬性來自輸入資料表資料欄。
  • 在 Account 節點中,name 屬性是指輸入資料表的 nick_name 欄。
  • 在 Account 節點中,name 屬性會使用 OPTIONS 子句提供屬性說明、同義詞清單,以及中繼資料鍵/值組合清單。

指定選項

您可以在標籤或屬性定義 (包括測量定義) 的 OPTIONS() 子句中,指定使用者定義的自訂中繼資料。支援的選項如下:

  • description:標籤或屬性的人類可讀字串說明。
  • synonyms:代表標籤或屬性同義詞的字串陣列。
  • extensions:代表其他中繼資料的字串組合陣列 (ARRAY<STRUCT<STRING, STRING>>)。您可以使用擴充功能提供自訂中繼資料、單位或格式規則,例如 [('currency', 'USD')]。

這些選項可提供背景資訊,並提高自然語言查詢介面的曝光度。您無法直接在圖表查詢中存取這些欄位,而且這些欄位不會以任何方式變更 GQL 查詢結果。

標籤和屬性一致性

在圖表中,標籤和屬性會以名稱做為不重複 ID。您可以在多個節點或邊緣定義中使用相同名稱的標籤和屬性。不過,名稱相同的標籤和屬性必須遵循下列規則:

  • 名稱相同的屬性必須使用相同的值類型。
  • 名稱相同的標籤必須顯示相同的屬性清單。

在上述範例中,Person 和 Account 節點都定義了 Entity 標籤。這兩個定義包含同一組屬性名稱 id 和 name,且值類型相同。

管理結構定義依附元件

圖形取決於節點和邊緣定義的輸入資料表結構定義,以及屬性參照的資料表資料欄。BigQuery Graph 不會檢查刪除或變更資料表或資料欄,是否會導致現有圖表結構定義失效。

您有責任避免破壞結構定義變更。請按照下列最佳做法操作:

  • 刪除圖表節點定義中使用的資料表前,請先從圖表中移除該節點定義。
  • 從圖表中公開為屬性的資料表移除資料欄之前,請先從對應的節點或邊定義中移除該屬性。

查看圖表結構定義

如要查看用於建構現有圖表的 CREATE PROPERTY GRAPH 陳述式,請查詢 INFORMATION_SCHEMA.PROPERTY_GRAPHS 檢視表:

SELECT
  property_graph_name,
  ddl
FROM
  `region-REGION`.INFORMATION_SCHEMA.PROPERTY_GRAPHS;

將 REGION 替換為圖表所在資料集的區域。

或者,您也可以在筆記本中以圖表呈現圖表結構定義。

更新圖表結構定義

如要變更現有圖表的結構定義,必須使用 CREATE PROPERTY GRAPH 陳述式重新定義圖表結構定義。

刪除圖表結構定義

如要刪除圖表,請使用 DROP PROPERTY GRAPH 陳述式。

最佳做法

以下各節說明定義圖表結構定義的最佳做法,有助於提升圖表查詢效能。

定義屬性範圍

屬性是鍵/值組合,可提供附加至節點或邊緣的其他資訊。建議您只在節點或邊緣中加入必要屬性,並避免使用 PROPERTIES ALL COLUMNS 語法或預設語法,將節點或邊緣資料表中的所有資料欄附加至屬性清單。如果節點或邊緣有許多屬性,圖表查詢可能會不必要地掃描資料欄,導致效能降低。

如要限制節點或邊緣定義中包含的屬性,請在 CREATE PROPERTY GRAPH 陳述式中定義元素屬性時,使用 PROPERTIES 關鍵字。

下列節點資料表定義會將 Person 節點資料表的屬性限制為 id 和 name:

NODE TABLES (
  graph_db.Person PROPERTIES (id, name)
)

定義圖表節點和邊緣的主鍵和外鍵限制

BigQuery 可在節點和邊緣資料表上使用主鍵和外鍵限制,減少不必要的資料表掃描,進而最佳化圖表查詢。不過,BigQuery 不會對資料表強制執行主鍵或外鍵限制。如果應用程式無法保證參照完整性或主鍵的唯一性,則使用主鍵或外鍵進行查詢最佳化,可能會導致查詢結果不正確。

以下範例定義節點資料表 Person 和 Account,以及邊資料表 PersonOwnAccount 的主鍵和外鍵限制:

CREATE OR REPLACE TABLE graph_db.Person (
  id               INT64,
  name             STRING,
  birthday         TIMESTAMP,
  country          STRING,
  city             STRING,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE OR REPLACE TABLE graph_db.Account (
  id               INT64,
  create_time      TIMESTAMP,
  is_blocked       BOOL,
  nick_name        STRING,
  PRIMARY KEY (id) NOT ENFORCED
);

CREATE OR REPLACE TABLE graph_db.PersonOwnAccount (
  id               INT64 NOT NULL,
  account_id       INT64 NOT NULL,
  create_time      TIMESTAMP,
  PRIMARY KEY (id, account_id) NOT ENFORCED,
  FOREIGN KEY (id) references graph_db.Person(id) NOT ENFORCED,
  FOREIGN KEY (account_id) references graph_db.Account(id) NOT ENFORCED
);

後續步驟