首页 文章

用于图数据库的PostgreSQL CTE语句

提问于
浏览
0

我在Postgres中使用CTE并不是很强大,但我认为这是我得到的图形问题的正确方向 . 我要做的是使用我的边缘表和最短路径数组生成一个SQL语句 . 我有两个图:数据和架构 . 数据图包含所有数据(显然),模式图描述了不同节点类型如何组合在一起 .

我不是递归地遍历已经很大且不断增长的数据图,而是创建了一个模式图,我想用它来生成数据图的查询 . 如果可能的话,它会明显更快 .

假设我有以下表格:

Node Type (架构图)

  • 患者(node_type_id = 1)

  • 入场(node_type_id = 12)

  • 访问(node_type_id = 15)

Node Type Edge (架构图)

  • 来源

  • 目标

Nodes (数据图表)

  • node_id

  • node_type_id

  • 有效载荷

Edges (数据图表)

  • 来源

  • 目标

我还有一个最短路径函数,它将路径作为模式的整数数组返回 . 例如:{15,12,1}将相当于Visit JOINS Admission JOIN Patient

我要做的是生成一个动态select语句来查询节点 . 所以,考虑到{15,12,1}以上的数组,我希望输出类似于:

SELECT n.node_id, n.payload
   FROM nodes n
   JOIN node_type_edges a
     ON n.node_type_id = a.source
   JOIN node_type_edges b
     ON a.target = b."source"
  WHERE a.source = 15
    AND b.source = 12
    AND b.target = 1;

这只是一个例子 . 现实是数据以各种深度连接,由客户在创建模式时定义 .

我认为某种递归的CTE声明会这样做,但我完全陷入困境 .

pass 1 -> SELECT n.node_id, n.payload
pass 1 ->   FROM nodes n
pass 1 ->   JOIN node_type_edges a
pass 1 ->     ON n.node_type_id = a.source
pass 2 ->   JOIN node_type_edges b
pass 2 ->     ON a.target = b."source"
pass 1 ->  WHERE a.source = 15
pass 2 ->    AND b.source = 12
pass 3 ->    AND b.target = 1;

这甚至可能吗?有人有更好的建议吗?在此先感谢您的任何建议!

1 回答

  • 0

    你有一个基本的误解 . 图形不是Trees,即没有从A-> B开始的唯一路径 . DB如何确定您想要的路径?

    另外,如何避免双向边的循环?你根本做不到 . 换句话说,关系数据库不能用于遍历图 . 这就是为什么,有专门的图形数据库,如Neo4j,特别是为此 .

    关于树木,你总是可以参考Joe Celko的“Trees and Hierarchies in SQL for Smarties

相关问题