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 不使用 Gist 索引 为啥?
从使用物化路径编码树的表中选择,按深度优先排序(无递归/ltree)