这是我正在使用的课程:https://gist.github.com/2174233
我有两个表:一个表包含用户,另一个表包含闭包。
当我使用get_children()
方法时(比如说来自root或其他父级),它只显示层次结构的第一级。我应该在lvl
列中存储哪些值?
这是闭包表的定义,我有:
CREATE TABLE closures (
id INT(11) NOT NULL AUTO_INCREMENT,
ancestor INT(11) NOT NULL,
descendant INT(11) NOT NULL,
lvl INT(11) NOT NULL,
PRIMARY KEY (id)
)
以下是我存储在闭包表中的数据示例:
INSERT INTO `closures` (`id`, `ancestor`, `descendant`, `lvl`)
VALUES (1, 1, 20, 0),
(4, 20, 26, 0),
(5, 26, 25, 0);
最后一个是lvl
列,但我不知道,那里有什么价值。你能给我一个如何使用它的建议吗?
我必须存储的结构有3个级别:root - > 20节点 - > 26节点,但它只给我20个节点的第一级子节点。
答案 0 :(得分:3)
我建议您选择SQL Antipatterns本书。第二章将闭包表作为实现类别树的推荐方法之一。
那就是说。看起来你的闭包表有点奇怪。 id
列中没有任何意义。相反,你应该有一个复合主键,由唯一的祖先和后代值组成。
你还没有自己插入节点..只有两个不同节点之间的连接。也许阅读"Rendering Trees with Closure Tables"可以对这个主题有所启发。
猜测INSERT
语句应如下所示(至少my conclusion}:
INSERT INTO closures(ancestor, descendant, lvl)
VALUES (1, 1, null),
(20, 20, null),
(26, 26, null),
(28, 28, null),
(1, 20, 1),
(20, 26, 2),
(26, 25, 3);
您必须了解的是,闭包表不存储树。相反,您正在使用的数据结构是方向图。像这样:
如您所见,此图表有三个根节点:3,5和7.另外,需要注意的是,节点10的深度级别不同,具体取决于你开始的根节点。
它将被定义为两个闭包:[3,10,1]和[11,10,2]。意思是,从第11个节点开始的连接会使它成为第2级,而从第3个节点开始,它是第一级项目。
事实是,当您使用闭包表时,每个类别可以有多个不同深度级别的父类别。
加法(@ypercube):
我对“级别”或“深度”列的理解是它存储了从祖先到目标的“距离”(步骤)。它不是节点的绝对级别,因此闭包表可用于存储比树图更复杂的表。您甚至可以拥有从祖先到后代的多条路径,每条路径都有不同的步骤。
此外,Null应为0,还需要更多行。
所以,数据将是:
INSERT INTO closures(ancestor, descendant, lvl)
VALUES ( 1, 1, 0), (20, 20, 0), (26, 26, 0), (25, 25, 0),
( 1, 20, 1), (20, 26, 1), (26, 25, 1),
( 1, 26, 2), (20, 25, 2),
( 1, 25, 3) ;