Hans-Juergen Schoenig:在 PostgreSQL 中使用 SQL/PGQ 处理图

Hans-Juergen Schoenig:在 PostgreSQL 中使用 SQL/PGQ 处理图

💡 原文英文,约1000词,阅读约需4分钟。
📝

内容提要

PostgreSQL 19 将支持 SQL/PGQ,允许直接在关系表上定义属性图并用 GRAPH_TABLE 查询,无需扩展或复制数据。文章以小型社交网络为例,演示 CREATE PROPERTY GRAPH、顶点与边查询、有向与无向遍历、查找朋友的朋友及 WHERE 过滤,执行计划显示查询被重写为普通 SQL,无额外执行节点。

🔎

延伸解读

无需扩展与数据复制,图查询直接基于现有表

SQL/PGQ 的核心优势在于不引入额外扩展,也不复制数据。CREATE PROPERTY GRAPH 只是在关系表之上定义元数据,将现有表映射为顶点和边。这意味着开发者可以直接在已有数据上使用图查询语法,无需迁移或同步数据,降低了使用门槛和运维成本。

有向与无向遍历的语义差异及性能影响

在边模式中,箭头方向决定遍历方向:-> 表示沿声明方向,<- 表示反向,而 - 表示无向。无向遍历会编译为 OR 条件,可能导致结果重复或行数翻倍。因此,除非数据本身对称,否则应明确指定方向,以避免错误结果和不必要的性能开销。

GRAPH_TABLE 查询被重写为普通 SQL,无额外执行节点

通过 EXPLAIN 可以看到,GRAPH_TABLE 查询最终被重写为常规 SQL 连接,执行计划中没有新增的图执行节点。这表明 SQL/PGQ 主要是一种语法糖,旨在简化图模式表达,而非引入新的执行引擎。因此,其性能特征与手写等效 SQL 基本一致。

WHERE 子句可置于 GRAPH_TABLE 内部进行过滤

在查找朋友的朋友时,可能会遇到循环路径(如 Alice -> Bob -> Alice)。文章演示了将 WHERE 子句放在 GRAPH_TABLE 定义内部来过滤这类行。这种写法允许在模式匹配过程中直接应用条件,使查询更紧凑,也避免了外部过滤可能带来的语义混淆。

❓

Q&A

PostgreSQL 19 中 SQL/PGQ 是什么?

SQL/PGQ 是 ISO/IEC 9075-16 (2023) 标准中定义的图查询语法,允许在常规关系表上直接查询图数据。PostgreSQL 19 将支持这一功能,无需安装扩展或复制数据。

如何在 PostgreSQL 中创建属性图?

使用 CREATE PROPERTY GRAPH 语句定义属性图。它基于现有关系表,将表映射为顶点和边,并指定标签和属性。例如,将 person 表定义为 person 顶点,knows 表定义为边。

GRAPH_TABLE 查询的基本语法是什么?

GRAPH_TABLE 用于在 SQL 中查询属性图。基本语法为:SELECT ... FROM GRAPH_TABLE (graph_name MATCH (pattern) COLUMNS (column_list))。其中 MATCH 定义图模式,COLUMNS 指定返回的列。

在 SQL/PGQ 中如何表示有向和无向边?

有向边使用箭头表示:-> 表示沿声明方向(从源到目标),<- 表示反向。无向边使用 - 表示,会沿两个方向遍历,结果可能包含重复行。

如何用 SQL/PGQ 查找朋友的朋友?

通过扩展图模式,添加第二个边跳转。例如:MATCH (a IS person)-[IS knows]->(b IS person)-[IS knows]->(c IS person),然后可以在 GRAPH_TABLE 内使用 WHERE 子句过滤掉自环等无意义结果。

SQL/PGQ 查询在 PostgreSQL 内部是如何执行的?

PostgreSQL 会将 SQL/PGQ 查询重写为普通的 SQL 查询,执行计划中不会出现额外的执行节点。这意味着图查询最终转化为对关系表的连接操作,性能与手写 SQL 相当。

🏷️

标签

➡️

继续阅读