SQL 图形体系结构
适用于: sql Server 2017 (14.x) 及更高版本Azure SQL 数据库 Microsoft Fabric 中的 SQL 数据库Azure SQL 托管实例 SQL 数据库
了解 SQL Graph 的体系结构。 了解基础知识可以更轻松地了解其他 SQL Graph 文章。
SQL Graph 数据库
用户可以为每个数据库创建一个图形。 图形是节点表和边缘表的集合。 可以在数据库中的任何架构下创建节点或边缘表,但它们都属于一个逻辑图。 节点表是类似类型的节点的集合。 例如,节点 Person
表保存属于图形的所有 Person
节点。 同样,边缘表是类似类型的边缘集合。 例如, Friends
边缘表包含连接到另一 Person
个 Person
边缘的所有边缘。 由于节点和边缘存储在表中,常规表上支持的大多数操作在节点表或边缘表上都受支持。
下图显示了 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>
列上。
Edge 表
边缘表表示关系图中的关系。 边缘始终定向并连接两个节点。 边缘表使用户可以在图形中对多对多关系建模。 用户定义的列(“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_desc
视图中的graph_type
sys.columns
列有助于了解图形节点和边缘表中使用的不同类型的列:
列名称 | 数据类型 | 描述 |
---|---|---|
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 | “到节点”的内部 object_id 版本。 |
to_id_\<hex_string> |
BIGINT | 1 | “到节点”的内部图形 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 中引入的 Transact-SQL 扩展,以及启用创建和查询图形对象的Azure 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 。 尝试在或$edge_id 列中插入值$node_id 会导致错误。 在插入边缘表中时,用户必须提供值 $from_id 和 $to_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
边缘的列和列。 若要更新边缘引用的节点,用户必须插入指向新节点的新边缘,并删除上一个边缘。 - 不支持对图形对象进行跨数据库查询。
- 图形伪列(
node_id
和$from_id
edge_id
$to_id
)不能用作有序聚集列存储索引的排序列。 尝试使用任何图形伪列作为有序聚集列存储的排序列会导致Msg 102: Incorrect syntax
错误。 - 在 Fabric SQL 数据库中,允许 SQL Graph,但 Node 和 Edge 表不会镜像到 Fabric OneLake。
另请参阅
后续步骤
- 若要开始使用 SQL Graph,请参阅 SQL Graph 数据库 - 示例