SQL 图形体系结构

适用于: SQL Server 2017 (14.x) 及更高版本 Azure SQL 数据库Azure SQL 托管实例

了解 SQL Graph 的体系结构。 了解基础知识后,可以更轻松地了解其他 SQL Graph 文章。

SQL Graph 数据库

用户可以为每个数据库创建一个图形。 图形是节点表和边缘表的集合。 可以在数据库中的任何架构下创建节点或边缘表,但它们都属于一个逻辑图。 节点表是类似类型节点的集合。 例如, Person 节点表包含属于图形的所有 Person 节点。 同样,边缘表是类似类型边缘的集合。 例如,边缘Friends表包含将 连接到另一PersonPerson 的所有边缘。 由于节点和边缘存储在表中,节点或边缘表支持常规表上支持的大多数操作。

下图显示了 SQL Graph 数据库体系结构。

显示 SQL Graph 数据库体系结构的关系图。

节点表

节点表表示图形架构中的实体。 每次创建节点表以及用户定义的列时,都会创建一个隐式 $node_id 列,该列唯一标识数据库中的给定节点。 中的 $node_id 值是自动生成的,是该节点表的图形表的对象 ID 和内部生成的 bigint 值的组合。 但是,选择列时 $node_id ,将显示 JSON 字符串形式的计算值。 此外, $node_id 是映射到具有唯一后缀的内部名称的伪列。 从表中选择 $node_id 伪列时,列名称显示为 $node_id_<unique suffix>

备注

在查询中使用伪列是查询内部 $node_id 列的唯一受支持和建议方式。 不应在任何查询中 $node_id_<hex_string> 直接使用这些列。 此外,伪列中显示的计算 JSON 表示形式是实现详细信息。 不应直接依赖于该 JSON 表示形式的格式。 如果必须处理此 JSON 表示形式,请考虑使用 NODE_ID_FROM_PARTS () 和其他相关的 系统函数。 不建议在谓词中直接使用图伪列 ($node_id$from_id$to_id) 。 例如,应避免使用类似于 的 n.$node_id = e.$from_id 谓词。 由于转换为 JSON 表示形式,此类比较往往效率低下。 请尽可能依赖 MATCH 函数。

建议用户在创建节点表时对 $node_id 列创建唯一约束或索引,但如果未创建,则会自动创建默认的唯一非聚集索引。 但是,图形伪列上的任何索引都是在基础内部列上创建的。 也就是说,在列上 $node_id 创建的索引显示在内部 graph_id_<hex_string> 列上。

边缘表

边缘表表示关系图中的关系。 边缘始终是定向的,并连接两个节点。 边缘表使用户能够在图形中为多对多关系建模。 用户定义的列 (“attributes”) 在边缘表中是可选的。 每次创建边缘表以及用户定义的列时,都会在边缘表中创建三个隐式列:

列名称 说明
$edge_id 唯一标识数据库中的给定边缘。 它是生成的列,值是边缘表object_id和内部生成的 bigint 值的组合。 但是,选择列时 $edge_id ,将显示 JSON 字符串形式的计算值。 $edge_id 是映射到具有唯一后缀的内部名称的伪列。 从表中选择 $edge_id 时,列名称显示为 $edge_id_<unique suffix>。 在查询中使用伪列名称是查询内部 $edge_id 列的建议方法,应避免将内部名称与十六进制字符串一起使用。
$from_id $node_id存储边缘源自的节点的 。
$to_id $node_id存储边缘终止的节点的 。

给定边缘可以连接到的节点由 插入到 $from_id$to_id 列中的数据控制。 在第一个版本中,不能对边缘表定义约束,以限制它连接任意两种类型的节点。 也就是说,无论节点的类型如何,边缘都可以连接图中的任何两个节点。

$node_id 列类似,建议用户在创建边缘表时对 $edge_id 列创建唯一索引或约束,但如果未创建,则会自动在此列上创建默认唯一的非聚集索引。 但是,图形伪列上的任何索引都是在基础内部列上创建的。 也就是说,在列上 $edge_id 创建的索引显示在内部 graph_id_<unique suffix> 列上。 对于 OLTP 方案,还建议用户在 ($from_id) $to_id 列上创建索引,以便更快地沿边缘方向查找。

下图显示了如何在数据库中存储节点表和边缘表。

显示节点表和边缘表表示形式的关系图。

元数据

使用这些元数据视图可以查看节点或边缘表的属性。

sys.tables

sys.tables 中的以下bit列可用于标识图形表。 如果 is_node 设置为 1,则表为节点表,如果 is_edge 设置为 1,则表为边缘表。

列名 数据类型 说明
is_node bit 对于节点表, is_node 设置为 1。
is_edge bit 对于边缘表, is_edge 设置为 1。

sys.columns

graph_type视图中的 sys.columnsgraph_type_desc 列有助于了解图形节点表和边缘表中使用的不同类型的列:

列名 数据类型 说明
graph_type int 具有一组值的内部列。 对于图形列,这些值介于 1-8 之间;对于其他列,为 NULL
graph_type_desc nvarchar(60) 具有一组值的内部列。

下表列出了列的有效值 graph_type

列值 说明
1 GRAPH_ID
2 GRAPH_ID_COMPUTED
3 GRAPH_FROM_ID
4 GRAPH_FROM_OBJ_ID
5 GRAPH_FROM_ID_COMPUTED
6 GRAPH_TO_ID
7 GRAPH_TO_OBJ_ID
8 GRAPH_TO_ID_COMPUTED

sys.columns 还存储有关在节点或边缘表中创建的隐式列的信息。 可以从 sys.columns 检索以下信息,但是,用户无法从节点或边缘表中选择这些列。

节点表中的隐式列包括:

列名 数据类型 is_hidden 评论
graph_id_\<hex_string> BIGINT 1 内部图形 ID 值。
$node_id_\<hex_string> NVARCHAR 0 节点 ID 的外部字符表示形式。

边缘表中的隐式列包括:

列名 数据类型 is_hidden 评论
graph_id_\<hex_string> BIGINT 1 内部图形 ID 值。
$edge_id_\<hex_string> NVARCHAR 0 边缘 ID 的字符表示形式。
from_obj_id_\<hex_string> INT 1 “from node”的内部 object_id 值。
from_id_\<hex_string> BIGINT 1 “from node”的内部图形 ID 值。
$from_id_\<hex_string> NVARCHAR 0 “from node”的字符表示形式。
to_obj_id_\<hex_string> INT 1 “to 节点”的内部 object_id
to_id_\<hex_string> BIGINT 1 “to 节点”的内部图形 ID 值。
$to_id_\<hex_string> NVARCHAR 0 “to node”的外部字符表示形式。

系统函数

可以使用以下内置函数与图形表中的伪列进行交互。 在相应的 T-SQL 函数引用中为每个函数提供了详细的引用。

内置 说明
OBJECT_ID_FROM_NODE_ID node_id中提取图形表的对象 ID。
GRAPH_ID_FROM_NODE_ID node_id中提取图形 ID 值。
NODE_ID_FROM_PARTS 从图形表的对象 ID 和图形 ID 值构造node_id。
OBJECT_ID_FROM_EDGE_ID edge_id中提取图形表的对象 ID。
GRAPH_ID_FROM_EDGE_ID 提取给定 edge_id的图形 ID 值。
EDGE_ID_FROM_PARTS 从图形表的对象 ID 和图形 ID 值构造 edge_id

Transact-SQL 参考

了解 SQL Server 和 Azure SQL Database 中引入的 Transact-SQL 扩展,这些扩展支持创建和查询图形对象。 查询语言扩展有助于使用 ASCII 艺术语法查询和遍历图形。

数据定义语言 (DDL) 语句

任务 相关文章 说明
CREATE TABLE CREATE TABLE (Transact-SQL) CREATE TABLE 现已扩展,支持创建表 AS NODE 或 AS EDGE。 边缘表可能具有任何用户定义的属性,也可能不具有任何属性。
ALTER TABLE ALTER TABLE (Transact-SQL) 可以使用 以与关系表相同的方式更改节点表和边缘表 ALTER TABLE。 用户可以添加或修改用户定义的列、索引或约束。 但是,更改内部图形列(如 $node_id$edge_id)会导致错误。
CREATE INDEX CREATE INDEX (Transact-SQL) 用户可以对节点表和边缘表中的伪列和用户定义的列创建索引。 支持所有索引类型,包括聚集和非聚集列存储索引。
CREATE EDGE 约束 EDGE 约束 (Transact-SQL) 用户现在可以对边缘表创建边缘约束,以强制实施特定语义并维护数据完整性
DROP TABLE DROP TABLE (Transact-SQL) 可以使用 以与关系表相同的方式删除节点表和边缘表 DROP TABLE。 目前,没有任何机制可以阻止删除边缘引用的节点。 在删除节点 (或删除整个节点表) 时,不支持级联删除边缘。 在所有此类情况下,必须手动删除连接到已删除节点的任何边缘,以保持图形的一致性。

数据操作语言 (DML) 语句

任务 相关文章 说明
INSERT INSERT (Transact-SQL) 插入节点表与插入关系表没有什么不同。 列的值 $node_id 是自动生成的。 尝试在 $node_id$edge_id 列中插入值会导致错误。 在插入到边缘表中时,用户必须为 和 $to_id 列提供值$from_id$from_id$to_id$node_id 给定边缘连接的节点的值。
DELETE DELETE (Transact-SQL) 节点表或边缘表中的数据的删除方式与从关系表中删除数据的方式相同。 但是,在此版本中,没有任何约束可以确保在删除节点时,没有任何边缘指向已删除的节点,并且不支持对边缘进行级联删除。 建议每当删除某个节点时,也会删除该节点的所有连接边缘。
UPDATE UPDATE (Transact-SQL) 可以使用 UPDATE 语句更新用户定义列中的值。 无法更新内部图形列、$node_id$edge_id$from_id$to_id
MERGE MERGE (Transact-SQL) MERGE 节点或边缘表支持 语句。

查询语句

任务 相关文章 说明
SELECT SELECT (Transact-SQL) 由于节点和边缘存储为表,因此节点表和边缘表也支持大多数表操作。
MATCH MATCH (Transact-SQL) 引入 MATCH 内置功能是为了支持模式匹配和遍历图形。

限制

节点表和边缘表存在某些限制:

  • 本地或全局临时表不能是节点表或边缘表。
  • 表类型和表变量不能声明为节点表或边缘表。
  • 节点表和边缘表不能创建为系统版本控制的临时表。
  • 节点表和边缘表不能是内存优化表。
  • 用户无法使用 UPDATE 语句更新 $from_id 边缘的 和 $to_id 列。 若要更新边缘引用的节点,用户必须插入指向新节点的新边缘,并删除以前的边缘。
  • 不支持对图形对象进行跨数据库查询。

请参阅

后续步骤