在一个查询中按顺序排序DB树结构?

时间:2012-02-05 22:55:46

标签: database tree

我希望以前没有问过这个特殊问题(找不到任何类似的问题)。如果是这样,请轻轻地将我链接到页面。

我正在使用DB(MySQL - InnoDB)中的树结构,我有两个表 - nodes和node_index。第一个表(节点)保存实际数据,而node_index跟踪层次结构。 node_index表(它的重要部分)如下所示:

+-------------+-------------+--------+----------+
| node_id     | path        | depth  | order    |
+-------------+-------------+--------+----------+
| 0           | 0           | 1      | 1        |
| 1           | 0.1         | 2      | 1        |
| 2           | 0.2         | 2      | 2        |
| 3           | 0.2.3       | 3      | 1        |
| 4           | 0.2.4       | 3      | 2        |
| 5           | 0.5         | 2      | 3        |
+-------------+-------------+--------+----------+

Node_id是节点表中id的外键。对于这个问题的上下文,节点表的结构是什么并不重要。

现在,在生成完整的树时,我可以简单地从路径排序的node_index中选择所有内容,并且只在一个查询中获得正确的结构。问题是,这不遵守订单设置,因为对于每个父级+级别组合,这将按其ID排序节点,我需要更改这些节点并让订单列对节点进行排序。 例如,如果我交换节点编号3和4的顺序值,我希望它们显示在同一位置(在其父节点2下),但是将首先显示节点4。 我不能使用“ORDER BY path,order”,因为路径是唯一的并且总是覆盖order列。我试图添加一个名为parent_path的列,它只保留父节点的路径,并通过“ORDER BY parent_path,order”对它进行排序,但事实证明这是错误的,因为它将级别分组(首先我得到所有的 - 级别节点,然后是所有第二级节点等。)。

所以我的目标是在一个查询中正确获取树结构(子项在其父项下,然后按顺序列排序,而不是按其ID排序)。我当然可以使用递归并在许多查询中获取结构,但如果可以使用没有订单列的一个查询来完成,我想即使使用排序,也可以在一个查询中执行此操作。我相信在数据库方面更熟练的人可能会找到一种方法(某种类型的自我加入可能吗?)。

我一直在研究这个问题,谷歌搜索和搜索,但似乎没有人有这个问题。每个人都通过递归使用许多查询来解决它,但我希望数据库变得非常大,具有很多深度,我需要经常生成树。我认为递归是数据库不必要的负担。

很抱歉,如果这已经得到解答,或者我错过了一些基本而明显的解决方案。

谢谢你, 的Jakub

1 个答案:

答案 0 :(得分:1)

您可以做的是创建一个SortPath列。通常情况下,这可能是名称之类的,但在您的情况下,您希望使用Order列。它与您的路径列类似,但node_id编号将替换为您的订单编号。

我在这个答案中给出了一个如何做到这一点的例子:https://stackoverflow.com/a/2797724/39430