PostgreSQL-树状组织

Ant*_*ton 5 php ruby postgresql tree search

我正在一个需要分类树的项目中,分类树按ID,父级,标题表进行组织。在Postgres中检索类别及其子类别(以及完整树,如果根类别具有parent = 0的话)的最佳方法是什么?我正在寻找一个纯粹的数据库解决方案,但是如果有一种使用Ruby和PHP的方法-那就太好了。

主要目标是选择子句的速度,因为该表中的数据对于更新/插入/删除速度并不关键。

UPD:还将进行路径搜索,即从当前顶点(类别)到根类别的路径。

bob*_*nce 5

\n

检索类别及其子类别

\n
\n\n

如果您的子项深度有限,您可以使用自连接来完成此操作,例如。深两层:

\n\n
SELECT *\nFROM categories AS child\nLEFT JOIN categories AS parent ON parent.id=child.parent\nLEFT JOIN categories AS grandparent ON grandparent.id=parent.parent\nWHERE child.id=(id) OR parent.id=(id) OR grandparent.id=(id);\n
Run Code Online (Sandbox Code Playgroud)\n\n

您无法在 \xe2\x80\x98parent-id-foreign-key\xe2\x80\x99 类型架构上使用标准 SQL 对任意深度的层次结构执行此操作。

\n\n

一些 DBMS 提供非标准的层次结构工具,允许以各种方式执行类似的操作,但如果您想坚持使用跨 DBMS 兼容的代码,则需要将模式重新调整为表示层次结构的更好模型之一。两个流行的是:

\n\n
    \n
  • 嵌套集。将表示树的深度优先搜索的线性排序存储在目标表的两列中(如果您的目标具有显式排序,则您已经拥有其中一列)。

  • \n
  • 邻接关系。将每个祖先/后代对存储在单独的连接表中。

  • \n
\n\n

每种方法都有优点和缺点,并且有许多变体(例如稀疏嵌套集编号,AR 中的 \xe2\x80\x98distance\xe2\x80\x99),这可能会影响各种类型的添加/删除/移动位置的昂贵程度操作是。就我个人而言,我倾向于默认使用简化的嵌套集模型,因为它比 AR 包含更少的冗余。

\n