Postgres 递归 LTREE 查找

Posted

技术标签:

【中文标题】Postgres 递归 LTREE 查找【英文标题】:Postgres recursive LTREE lookup 【发布时间】:2020-04-28 12:24:43 【问题描述】:

我有以下两个代表嵌套文件夹层次结构的表

表“文件夹”包含基本文件夹信息

+----+--------------+
| id |     name     |
+----+--------------+
|  1 | Top          |
|  2 | Science      |
|  3 | Astronomy    |
|  5 | Astrophysics |
|  6 | Cosmology    |
+----+--------------+

表“folder_tree”包含层次结构,使用 LTREE 类型的文件夹 ID 和列路径。

+----+--------+---------+
| id | folder | path    |
+----+--------+---------+
| 32 | 1      | 1       |
| 33 | 2      | 1.2     |
| 36 | 3      | 1.2.3   |
| 37 | 4      | 1.2.3.4 |
| 38 | 5      | 1.2.3.5 |
+----+--------+---------+

当给定结构数组时,我希望验证是否存在确切的文件夹结构,例如如何按顺序验证 ['Top'、'Science'、'Astronomy'、'Astrophysics']。

我相信递归查询是可行的,它首先查看根文件夹“Top”,然后向下搜索到 Astrophysics,确认沿途存在每个文件夹。

这可以通过递归查询来实现吗?还是类似的?

我了解 folder_tree 的路径可能包含完全类似于 Top.Science.etc 的名称,但在这种情况下,文件夹名称包含 LTREE 中不允许的空格和符号。

【问题讨论】:

这是一个非常糟糕的设计,我鼓励您在继续应用程序开发之前对其进行重构。它有很多冗余,冗余容易出错,难以修改;例如,如果您想将文件夹“3”移动到其他位置,则需要更新多行数据,而不是单行数据,这会带来所有风险。 @TheImpaler 如何改进?我正在使用 LTREE - postgresql.org/docs/9.1/ltree.html 遵循 Postgres 文档中几乎完全相同的示例(除了我已将名称抽象到单独的表中) @jsrgnt:与您的问题无关,只是对未来的提示:您应该避免阅读过时 Postgres 版本(9.1)的手册。例如通过为“当前”版本的链接添加书签 @a_horse_with_no_name 感谢您的提醒!没想到 【参考方案1】:

这不是答案,而是不适合 cmets 部分的评论

PostgreSQL“ltree”专为快速检索和搜索而设计。对于需要原子修改、无锁、修改时避免并发问题的关系型数据库模型,这不是典型的解决方案。

如果这是一个 NoSQL 解决方案,那就没问题了。但是,在关系建模中,您将避免冗余。例如,您的两个表可以建模为一个:

+----+--------------+--------+
| id |     name     | parent |
+----+--------------+--------+
|  1 | Top          |   null |
|  2 | Science      |      1 |
|  3 | Astronomy    |      2 |
|  5 | Astrophysics |      3 |
|  6 | Cosmology    |      4 |
+----+--------------+--------+

【讨论】:

以上是关于Postgres 递归 LTREE 查找的主要内容,如果未能解决你的问题,请参考以下文章

Postgres 中的 LTREE 祖先查询未按预期工作

休眠查询中的 Postgres ltree

Postgres ltree 不使用 Gist 索引 为啥?

从使用物化路径编码树的表中选择,按深度优先排序(无递归/ltree)

使用 Postgres 范围的递归 SQL 查询以查找可用性

递归查找数据库生成list包含 tuple的情况