这是我的数据结构,看起来像一棵节点树,我将所有节点保存在一个递归表中:
Id | Name | ParentId | Level
-----------------------------------
1 | Node1 | NULL | 1
2 | Node2 | NULL | 1
3 | Node3 | 1 | 2
4 | Node4 | 1 | 2
5 | Node5 | 3 | 3
6 | Node6 | 3 | 3
7 | Node7 | 3 | 3
8 | Node8 | 4 | 3
9 | Node9 | 6 | 4
10 | Node10 | 6 | 4
11 | Node11 | 8 | 4
12 | Node12 | 10 | 5
我遇到的问题是检索一个Node的子代和父代执行得不是很好,我试图调用递归函数来获取子代和父代。例如Node6
retrieveAllChildrenof(6){} -> return 9,10,12;
retrieveAllParentsof(6){} -> return 3,1;
所以我只是想添加一个新列以避免递归函数,就像这样:
Id | Name | ParentId | Level | Trace
---------------------------------------------
1 | Node1 | NULL | 1 | 1
2 | Node2 | NULL | 1 | 2
3 | Node3 | 1 | 2 | 1-3
4 | Node4 | 1 | 2 | 1-4
5 | Node5 | 3 | 3 | 1-3-5
6 | Node6 | 3 | 3 | 1-3-6
7 | Node7 | 3 | 3 | 1-3-7
8 | Node8 | 4 | 3 | 1-4-8
9 | Node9 | 6 | 4 | 1-3-6-9
10 | Node10 | 6 | 4 | 1-3-6-10
11 | Node11 | 8 | 4 | 1-4-8-11
12 | Node12 | 10 | 5 | 1-3-6-10-12
现在有了跟踪字段,我可以将孩子和父母检索为:
retrieveAllChildrenof(6){} ->
//Trace(6) = 1-3-6; GetAllNodesThatStartWithTrace(1-3-6) => 9,10,12;
retrieveAllParentsof(6){} -> //Trace(6) = 1-3-6; GetNodesIdsIn(1-3); => 1,3;
我知道用逗号或破折号分隔的数据很难处理,但是有没有更好的方法可以在节点中导航并找到孩子和父母,有什么建议吗?
更新 目前,对于递归函数,我这样使用: CTE Recursion to get tree hierarchy
答案 0 :(得分:0)
如果树很少改变,则可以进行深度优先搜索,对到达的节点进行编号。节点的后代具有连续的编号,紧接在分配给该节点的编号之后,并且您可以使用一列来记录每个节点的编号,并使用一列来记录其最后一个后代的编号。然后,通过查找节点的编号,最后一个后代的编号,并检索所有在这两个节点之间具有编号的行,来检索该节点的所有后代。