Spanner 图架构概览

本文档介绍了 Spanner 图架构,并提供了 几个关键概念如需详细了解 Spanner 图,请参阅 Spanner Graph 概览

属性图表数据模型

借助属性图,您可以对关联的数据进行建模。它以 由多个节点和边组成的网络节点代表数据景观中的实体,例如“客户”“产品”或“地理位置”,边缘显示这些节点之间的连接,捕获“购买”“关注”或“位于”等关系。

节点和边都可以包含以下信息:

  • 标签,用于将节点和边划分为集合,例如城市。
  • 属性,即键值对,例如人口。

图 1 中的示例展示了如何设计图表来对金融活动进行建模。此图表包含以下类型的实体 建模为节点:

  • 个人:表示参与金融交易的个人。
  • 账号:表示用于交易的银行账户。

这些实体通过不同类型的关系相连,这些关系由以下有向边表示:

  • 拥有:用户拥有一个或多个账号。
  • 转账:资金从一个账户转移到另一个账户。

每个有向边表示从源节点流出的单向关系 连接到目标节点例如,Transfers 边缘会连接来源 Account到目的地 Account,表示资金流。

Spanner 图架构概览图。

图 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: 以下:

  • PersonAccount 个节点
  • 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 KEYDESTINATION KEYREFERENCES 子句。以下 示例使用 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; 通常映射到图中的唯一边。
  • 一行可能对应于图表中的零条或多条边,对于 例如,当 源节点参考 与源节点表中的零个或多个节点匹配。
  • 同一输入表可用于不同的节点或边定义 来创建不同的节点或边集。如需了解详情,请参阅合并节点和边输入表

自定义标签和属性

您可以使用 LABELPROPERTIES 子句自定义标签和属性。

在以下示例中,定义了两个节点,即 PersonAccount

  • Person 节点通过标签 exposeaddress 属性 Customer。通过 address 属性由表达式 CONCAT(city, ", ", country), 定义,该表达式引用输入中的 citycountry 列 表 Person
  • 对于 AccountAccount 节点公开 idcreate_time 通过 Account 标签添加属性。
  • PersonAccountEntity 标签具有属性 [id, name]。
    • 对于 Personidname 属性来自输入表列。
    • 对于 Accountname 属性引用输入表的 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)
  );

标签和房源一致性

在图表中,标签和属性由其名称唯一标识。 同名标签和属性可以在多个节点或边定义中出现。不过,具有相同名称的标签和媒体资源必须遵循以下规则:

  • 具有相同名称的属性必须具有相同的值类型。
  • 具有相同名称的标签必须公开相同的属性列表。

在前面的示例中,PersonAccount 节点中都定义了 Entity 标签。在这两种定义中,它们具有一组具有相同值类型的属性名称 [idname]。

图和其他架构对象之间的依赖关系

CREATE PROPERTY GRAPH 创建的图依赖于其他架构对象,例如节点和边定义的输入表,以及属性引用的表列。如果架构更改会破坏其中一个 依赖项,则不允许进行更改。

以下语句创建了从 FinGraphAccount 的依赖关系 以及 idcreate_time 列。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Account PROPERTIES (id, create_time)
  );

以下是不允许进行的架构更改示例:

不过,您可以进行以下架构更改:

  • 修改 Account 表以及 idcreate_time 列架构,前提是其他架构要求允许这样做。如需了解详情,请参阅进行架构更新

后续步骤