瞭解如何使用 SQL 檢視區塊建立圖表。本文提供逐步操作說明和程式碼範例,說明如何定義檢視區塊,並使用這些檢視區塊定義節點和邊緣資料表。請參閱範例,瞭解如何使用程式碼範例,展示透過檢視區塊建立圖表的用途。如要進一步瞭解如何使用檢視區塊建立屬性圖表,包括優點和注意事項,請參閱「透過 SQL 檢視區塊建立圖表總覽」。
事前準備
如要建立圖表,請務必:
確認 Spanner 圖表環境已設定完成。
使用檢視區塊建立圖表
如要使用檢視區塊建立圖表:
在
CREATE PROPERTY GRAPH陳述式的NODE TABLES和EDGE TABLES子句中使用檢視畫面,建立圖表。在
CREATE PROPERTY GRAPH陳述式中加入KEY子句。KEY子句會指定來源檢視區塊中的資料欄,這些資料欄可識別每個圖表元素。
範例:使用檢視區塊建立圖表
這個範例會在 Customer 和 Account 資料表上建立下列檢視區塊:AsiaCustomer、AsiaBankAccount 和 AsiaAccountsOwnership。接著,範例會使用這些檢視畫面,在圖表中建立下列項目:
使用
AsiaCustomer檢視畫面建立Customer節點資料表。使用
AsiaBankAccount檢視畫面建立Account節點資料表。使用
AsiaAccountsOwnership檢視畫面建立Owns邊緣資料表。這個邊緣會將Customer節點與Account節點連結。
步驟 1:建立表格
首先,請建立資料表。下列程式碼會建立 Customer 和 Account 資料表。
CREATE TABLE Customer (
customer_id INT64 NOT NULL,
name STRING(MAX),
address_continent STRING(MAX),
address_country STRING(MAX),
) PRIMARY KEY(customer_id);
CREATE TABLE Account (
account_id INT64 NOT NULL,
customer_id INT64 NOT NULL,
account_type STRING(MAX),
balance INT64,
create_time TIMESTAMP,
address_continent STRING(MAX),
address_country STRING(MAX),
CONSTRAINT FK_CustomerId FOREIGN KEY (customer_id)
REFERENCES Customer (customer_id)
) PRIMARY KEY(account_id);
步驟 2:建立檢視畫面
接著,建立檢視區塊來轉換或篩選資料表中的資料。這些檢視畫面會篩選表格,只顯示亞洲的客戶和帳戶。用於建立圖表元素的檢視區塊必須確保檢視區塊中的資料列是唯一的。
-- View for 'Customer' nodes, filtered for Asia
CREATE VIEW AsiaCustomer
SQL SECURITY INVOKER AS
SELECT customer.customer_id, customer.name
FROM Customer customer
WHERE LOWER(customer.address_continent) = "asia";
-- View for 'Account' nodes, filtered for Asia.
CREATE VIEW AsiaBankAccount
SQL SECURITY INVOKER AS
SELECT account.account_id, account.balance, account.account_type, account.create_time
FROM Account account
WHERE LOWER(account.address_continent) = "asia";
-- View for 'Owns' edges, connecting customers to accounts in Asia.
CREATE VIEW AsiaAccountsOwnership
SQL SECURITY INVOKER AS
SELECT account.customer_id, account.account_id
FROM Account account
WHERE LOWER(account.address_continent) = "asia";
步驟 3:建立屬性圖
現在,請使用您建立的檢視區塊建立 AsiaFinGraph。CREATE PROPERTY GRAPH 陳述式包含每個圖表元素定義的 KEY 子句,用於指定可專屬識別圖表元素的資料欄。
CREATE PROPERTY GRAPH AsiaFinGraph
NODE TABLES (
AsiaCustomer AS Customer KEY(customer_id),
AsiaBankAccount AS Account KEY(account_id)
)
EDGE TABLES (
AsiaAccountsOwnership AS Owns
KEY(customer_id, account_id)
SOURCE KEY (customer_id) REFERENCES Customer (customer_id)
DESTINATION KEY (account_id) REFERENCES Account (account_id)
);
應用實例範例
與使用資料表做為屬性圖形元素相比,SQL 檢視區塊具有許多優點。下列範例說明如何使用檢視區塊 (而非表格) 定義圖表元素。
範例:強制執行精細的圖形資料存取權控管機制
如要在圖表資料上強制執行資料列層級安全防護機制,請使用定義者的權限檢視畫面定義節點或邊緣資料表。檢視畫面會向圖表公開允許的基礎資料子集
舉例來說,如要將圖表存取權限制為只有工程成本中心的員工可存取,您可以建立 EngineerEmployeeView 檢視畫面,並使用 GRANT 子句,將該檢視畫面的 SELECT 權限授予 engineering_data_reader 角色。
使用這個檢視區塊定義圖形節點資料表時,執行圖形查詢且具備 engineering_data_reader 角色的使用者,只能看到檢視區塊篩選出的資料列,包括工程員工。
-- The table containing all employee data.
CREATE TABLE Employee (
id INT64 NOT NULL,
cost_center STRING(MAX),
job_title STRING(MAX),
office STRING(MAX)
) PRIMARY KEY (id);
-- The definer's rights view that filters for engineering employees.
CREATE VIEW EngineerEmployeeView SQL SECURITY DEFINER AS
SELECT e.id, e.cost_center, e.job_title, e.office
FROM Employee e
WHERE LOWER(e.cost_center) = "engineering";
-- The role that is granted to read the view.
CREATE ROLE engineering_data_reader;
GRANT SELECT ON VIEW EngineerEmployeeView TO ROLE engineering_data_reader;
-- The graph that uses definer's rights view.
CREATE PROPERTY GRAPH EngineeringGraph
NODE TABLES (
EngineerEmployeeView KEY(id)
);
範例:模型衍生圖形元素
您可以使用檢視區塊定義需要資料轉換的圖表元素。主要優點是檢視畫面會定義轉換,因此您不需要維護衍生資料的獨立資料表。
舉例來說,您可以從 ARRAY 欄 (或 JSON 欄中的陣列欄位) UNNEST 資料,為單一資料列建立多個邊緣關係模型。
在下列供應鏈結構定義範例中,Parts 資料表會在 dependent_parts 陣列中儲存子元件清單。檢視畫面可以使用 UNNEST 運算子,將該陣列的每個元素轉換為不同的資料列。這個檢視畫面隨後可做為邊緣資料表,讓您建立 PartDependsOnPart 邊緣,代表零件之間的依附關係。
-- Parts table with an ARRAY of dependent parts.
CREATE TABLE Parts (
part_id INT64 NOT NULL,
dependent_parts ARRAY<INT64>
) PRIMARY KEY (part_id);
-- A view that unnests the dependent_parts array.
-- GROUP BY ensures uniqueness for the graph element KEY.
CREATE VIEW PartDependsOnPart SQL SECURITY INVOKER AS
SELECT p.part_id, dependent_part_id
FROM Parts AS p,
UNNEST(p.dependent_parts) AS dependent_part_id
GROUP BY p.part_id, dependent_part_id;
-- Graph modeling the part dependency relationship.
CREATE PROPERTY GRAPH SupplyChainGraph
NODE TABLES (
Parts
)
EDGE TABLES (
PartDependsOnPart KEY (part_id, dependent_part_id)
SOURCE KEY (part_id) REFERENCES Parts(part_id)
DESTINATION KEY (dependent_part_id) REFERENCES Parts(part_id)
);
範例:無結構定義資料轉換
無結構定義的資料管理可讓您建立彈性的圖表定義,不必預先定義節點和邊緣類型。無結構定義的資料管理方式雖然彈性,但隨著資料定義越來越明確,您可能需要改用更正式的結構。更正式的結構會公開結構定義中的圖形節點和邊緣關係、標籤和屬性,減少手動探索資料以瞭解圖形結構定義的需求。
您可以使用檢視區塊,正式化節點和邊緣類型,而不需遷移基礎資料。舉例來說,您可以從使用標準 GraphNode 和 GraphEdge 資料表的典型無結構定義模型轉換。如要這麼做,請建立從無結構定義資料表擷取資料的檢視區塊:
為要正式化的每個節點和邊緣類型定義檢視畫面 (例如
Person或WorksFor)。在檢視畫面中,依標籤 (例如WHERE n_label = "person") 篩選資料,並將 JSON 資料欄中的屬性轉換為特定資料類型 (例如STRING(prop.name) AS name)。定義新的屬性圖,其中
NODE TABLES和EDGE TABLES會參照您剛建立的型別檢視區塊。
對於某些查詢 (例如具有多個邊緣類型的量化路徑模式),無結構定義的圖表效能優於正式圖表。如果您的用途需要正式中繼資料,可以使用檢視區塊從無結構定義的圖形轉換為已輸入的結構定義。您也可以選擇在某些用途中使用無結構定義的圖形,在其他用途中使用型別架構圖形。詳情請參閱「根據圖表查詢選擇結構定義設計」。
以下範例說明如何透過四個步驟,從無結構定義轉換為正式圖表:
為無結構定義模型定義標準
GraphNode和GraphEdge資料表。在這些無結構定義的資料表上建立初始彈性圖形。
定義型別檢視區塊 (
Person、Company、WorksFor),從無結構定義的資料表擷取並正式化資料。建立最終的強型別圖表,並將這些檢視區塊做為節點和邊緣資料表。
-- 1. Create the canonical tables for a schemaless model.
CREATE TABLE GraphNode (
id INT64 NOT NULL,
label STRING(MAX) NOT NULL,
properties JSON
) PRIMARY KEY (id);
CREATE TABLE GraphEdge (
id INT64 NOT NULL,
dest_id INT64 NOT NULL,
edge_id INT64 NOT NULL,
label STRING(MAX) NOT NULL,
properties JSON
) PRIMARY KEY (id, dest_id, edge_id),
INTERLEAVE IN PARENT GraphNode;
-- 2. Define a schemaless graph.
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
GraphNode
DYNAMIC LABEL (label)
DYNAMIC PROPERTIES (properties)
)
EDGE TABLES (
GraphEdge
SOURCE KEY (id) REFERENCES GraphNode(id)
DESTINATION KEY (dest_id) REFERENCES GraphNode(id)
DYNAMIC LABEL (label)
DYNAMIC PROPERTIES (properties)
);
-- 3. Define typed views that extract and formalize the data.
-- Convert JSON fields to primitive types (for example, INT64, STRING) to
-- ensure type safety.
CREATE VIEW Person SQL SECURITY INVOKER AS
SELECT n.id, STRING(n.properties.name) AS name, INT64(n.properties.age) AS age
FROM GraphNode n WHERE n.label = "person";
CREATE VIEW Company SQL SECURITY INVOKER AS
SELECT n.id, STRING(n.properties.name) AS company_name, BOOL(n.properties.is_public) AS is_public
FROM GraphNode n WHERE n.label = "company";
CREATE VIEW WorksFor SQL SECURITY INVOKER AS
SELECT e.id AS person_id, e.dest_id AS company_id, e.edge_id AS edge_id, STRING(e.properties.since) AS since
FROM GraphEdge e
WHERE e.label = "worksfor";
-- 4. Create the final, formalized graph from the typed views.
CREATE PROPERTY GRAPH typed_formalized_graph
NODE TABLES (
Person KEY(id)
PROPERTIES (name, age),
Company KEY(id)
PROPERTIES (company_name, is_public)
)
EDGE TABLES(
WorksFor KEY(person_id, company_id, edge_id)
SOURCE KEY (person_id) REFERENCES Person(id)
DESTINATION KEY (company_id) REFERENCES Company(id)
PROPERTIES (since)
);