我希望以前没有问过这个特殊问题(找不到任何类似的问题)。如果是这样,请轻轻地将我链接到页面。
我正在使用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
答案 0 :(得分:1)
您可以做的是创建一个SortPath列。通常情况下,这可能是名称之类的,但在您的情况下,您希望使用Order
列。它与您的路径列类似,但node_id编号将替换为您的订单编号。
我在这个答案中给出了一个如何做到这一点的例子:https://stackoverflow.com/a/2797724/39430。