本文档介绍了 Spanner 图架构,并提供了 几个关键概念如需详细了解 Spanner 图,请参阅 Spanner Graph 概览。
属性图表数据模型
借助属性图,您可以对关联的数据进行建模。它以 由多个节点和边组成的网络节点代表数据景观中的实体,例如“客户”“产品”或“地理位置”,边缘显示这些节点之间的连接,捕获“购买”“关注”或“位于”等关系。
节点和边都可以包含以下信息:
- 标签,用于将节点和边划分为集合,例如城市。
- 属性,即键值对,例如人口。
图 1 中的示例展示了如何设计图表来对金融活动进行建模。此图表包含以下类型的实体 建模为节点:
- 个人:表示参与金融交易的个人。
- 账号:表示用于交易的银行账户。
这些实体通过不同类型的关系相连,这些关系由以下有向边表示:
- 拥有:用户拥有一个或多个账号。
- 转账:资金从一个账户转移到另一个账户。
每个有向边表示从源节点流出的单向关系
连接到目标节点例如,Transfers
边缘会连接来源
Account
到目的地 Account
,表示资金流。
图 1. 包含多个节点和有向边的图示例。
节点和边可以包含属性形式的其他信息。每个属性都有一个名称和值。
- Person 节点具有以下属性:
name
(STRING
)id
(INT64
)
- 转移边具有以下属性:
amount
(FLOAT64)
已导向边缘和无向边缘
示例图使用有向边,用于指明实体之间关系的特定方向。然而,也有一些关系,例如 “朋友”这类关系是无导向的, 互斥连接。在这种情况下 可以将无向边建模为两条指向边,每个方向上一条边。
Spanner Graph 架构设计
借助 Spanner Graph,您可以使用 CREATE PROPERTY GRAPH 语句根据表创建图表。用于创建图表的表格 称为输入表。这种方法基于 SQL/PGQ(属性图查询)、 是 SQL:2023 标准的一部分。
在属性图中定义节点
如需定义节点,请在 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
标签。 - 每个账号节点都有
[id, create_time]
从Account
个表格列。
元素键
节点定义还定义了元素键,该键用于唯一标识图节点。
- 默认情况下,元素键是输入表的主键。
- 元素键可以通过
KEY
子句明确定义。 - 具有唯一性约束条件
UNIQUE INDEX
的列可以用作元素键。
以下示例定义了 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
(目的地)节点。
- 边的
SOURCE
节点是Person
节点,其id
等于 边缘id
。 - 边的
DESTINATION
节点是Account
节点,其id
与边account_id
相同。
此外,对于 PersonOwnAccount
边,以下为真:
- 元素键是
PersonOwnAccount
表的主键,即(id, account_id)
。 - 每个边都具有与
PersonOwnAccount
表中的列相同的一组属性。 - 每个边都有默认的
PersonOwnAccount
标签。
将边输入表中的行映射到图中的边
- 边缘输入表中的每一行,其元素键不为 null; 通常映射到图中的唯一边。
- 一行可能对应于图表中的零条或多条边,对于 例如,当 源节点参考 与源节点表中的零个或多个节点匹配。
- 同一输入表可用于不同的节点或边定义 来创建不同的节点或边集。如需了解详情,请参阅合并节点和边输入表。
自定义标签和属性
您可以使用 LABEL 和 PROPERTIES 子句自定义标签和属性。
在以下示例中,定义了两个节点,即 Person
和 Account
。
Person
节点通过标签expose
了address
属性Customer
。通过address
属性由表达式CONCAT(city, ", ", country),
定义,该表达式引用输入中的city
和country
列 表Person
。- 对于
Account
,Account
节点公开id
和create_time
通过Account
标签添加属性。 Person
和Account
的Entity
标签具有属性 [id, name
]。- 对于
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)
);
标签和房源一致性
在图表中,标签和属性由其名称唯一标识。 同名标签和属性可以在多个节点或边定义中出现。不过,具有相同名称的标签和媒体资源必须遵循以下规则:
- 具有相同名称的属性必须具有相同的值类型。
- 具有相同名称的标签必须公开相同的属性列表。
在前面的示例中,Person
和 Account
节点中都定义了 Entity
标签。在这两种定义中,它们具有一组具有相同值类型的属性名称 [id
、name
]。
图和其他架构对象之间的依赖关系
CREATE PROPERTY 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
列架构,前提是其他架构要求允许这样做。如需了解详情,请参阅进行架构更新。