架构概览
本文档介绍了属性图表架构的组成部分,并向您展示了如何创建和管理图表架构。
借助图表,您可以对关联数据进行建模,将信息表示为由节点和边缘组成的网络。图表架构由节点和边缘组成,以及对节点和边缘类型进行分类的标签和描述节点和边缘的属性。 您可以通过将输入表中的行映射到图表节点和边缘并定义自定义标签和属性来定义属性图表架构。 如需详细了解 BigQuery Graph,请参阅 BigQuery Graph 概览。
了解属性图表数据模型
借助属性图表,您可以将关联数据建模为由节点和边缘组成的网络。节点表示数据中的实体,例如客户、产品或地点。边缘表示这些节点之间的连接,描述购买、关注或地点等关系。
节点和边缘都可以包含以下信息:
标签:对节点和边缘类型进行分类。例如,班级中的学生可能具有
Student标签和Person标签。 如果您未明确为节点或边缘定义标签,BigQuery Graph 会使用输入表名称作为默认标签。属性:用于描述节点和边缘。例如,表示人员的节点可能具有值为
Alex的name属性和值为1的id属性。
图 1 中的示例展示了如何设计图表来对金融活动进行建模。此图表包含以下类型的以节点形式建模的实体:
- Person:表示参与金融交易的个人。
- Account:表示用于交易的银行账户。
这些实体通过不同类型的关系(由以下有向边缘表示)相连:
- 拥有:一个人拥有一个或多个账号。
- Transfers:资金从一个账号转移到另一个账号。
每个有向边缘都表示一个单向关系,从来源节点流向目标节点。例如,Transfers 边缘将来源 Account 连接到目标
Account,从而表示资金流动。

图 1. 包含多个节点和有向边缘的示例图表。
节点和边缘可在属性中包含其他信息。
Person节点包含以下属性:name(STRING)id(INT64)
Transfers边缘包含以下属性:amount(FLOAT64)
有向边缘和无向边缘
有向边缘表示实体之间关系的特定方向。 例如,一个人拥有一个账号,但一个账号不拥有一个人。不过,某些关系(例如社交网络中的好友关系)是无向的,表示互惠连接。 在这种情况下,您可以将无向边缘建模为两个有向边缘,每个方向一个边缘。
设计架构
借助 BigQuery Graph,您可以使用
CREATE PROPERTY GRAPH
语句从表创建图表。用于创建图表的表称为“输入表”。
定义节点
节点由以下类型的表或视图中的行定义:
- 标准表
- 外部表
- Apache Iceberg 受管表
- Lakehouse Iceberg REST 目录表
- 视图,包括授权视图
- 非增量物化视图
如需定义节点,请在
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标签。 - 每个 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
);
- 具有非 null 元素键的每一行都会映射到图表中的唯一节点(该节点由元素键标识)。
- 系统会忽略具有 null 元素键的行。
同一个输入表可用于多个节点定义。在这种情况下,输入表中的给定行会映射到每个节点定义的一个节点。
定义边缘
边缘由以下类型的表或视图中的行定义:
- 标准表
- 外部表
- Apache Iceberg 受管表
- Lakehouse Iceberg REST 目录表
- 视图,包括授权视图
- 非增量物化视图
如需定义边缘,请将边缘定义添加到
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标签。
将行映射到边缘
边缘输入表中具有非 null 元素键的每一行通常都会映射到图表中的单个边缘。不过,如果来源或目标 节点引用与来源或目标节点 表中的零个或多个节点匹配,则边缘输入表中的行可能会导致图表中出现零个或多个 边缘。
在单个表中定义节点和边缘
如果表的列定义了与另一个表的关系,您可以在单个表中定义节点及其传入或传出边缘。这种方法可以减少表的数量,简化数据管理,并且无需联接到单独的边缘表,因此可以提高查询性能。
例如,如果以下 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'])
)
);
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子句提供属性的说明和同义词列表。这些字段提供上下文,并提高自然语言查询界面的可发现性。您无法在图表查询中直接访问这些字段,并且它们不会以任何方式更改查询结果。
标签和属性一致性
在图表中,标签和属性通过其名称进行唯一标识。 您可以在多个节点或边缘定义中使用具有相同名称的标签和属性。不过,具有相同名称的标签和属性必须遵循以下规则:
- 具有相同名称的属性必须使用相同的值类型。
- 具有相同名称的标签必须公开相同的属性列表。
在前面的示例中,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 语法或将节点或边缘表中的所有列附加到属性列表的默认
语法。在节点或边缘中包含许多属性可能会导致图表查询中出现不必要的列扫描,从而降低性能。
如需限制在节点或边缘定义中包含的属性,请使用
PROPERTIES关键字,在
定义元素属性
时,在您的CREATE PROPERTY GRAPH语句中使用。
以下节点表定义将 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
);
后续步骤
- 详细了解 BigQuery Graph。
- 了解如何 创建和查询属性图表。
- 了解如何编写图表查询。
- 详细了解如何使用 指标构建图表。