我已经和这个闭包表一起玩了一段时间。我遇到的问题是第二次出现后代。我有子类别的实例出现在多个父类别中。为简单起见,我已回归到这个例子:
drop table if exists closure;
drop table if exists nodes;
create table nodes (
node int auto_increment primary key,
label varchar(20) not null
);
insert into nodes (node, label) values
(1, 'rootree'),
(2, '1stbranch'),
(3, 'midbranch'),
(4, 'corebranch'),
(5, 'leafnodes'),
(6, 'lastbranch'),
(7, 'lastleaf');
create table closure (
ancestor int not null,
descendant int not null,
primary key (ancestor, descendant),
foreign key (ancestor) references nodes(node),
foreign key (descendant) references nodes(node)
);
insert into closure (ancestor, descendant) values
(1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7),
(2,2),
(3,3), (3,4), (3,5),
(4,4), (4,5),
(5,5),
(6,6), (6,7),
(7,7);
使用以下查询,我可以得到所需的结果:
select group_concat(n.label order by n.node separator ' -> ') as path
from closure d
join closure a on (a.descendant = d.descendant)
join nodes n on (n.node = a.ancestor)
where d.ancestor = 1 and d.descendant != d.ancestor
group by d.descendant;
结果:
rootree -> 1stbranch
rootree -> midbranch
rootree -> midbranch -> corebranch
rootree -> midbranch -> corebranch -> leafnodes
rootree -> lastbranch
rootree -> lastbranch -> lastleaf
但是,如果我添加另一个孩子,一个已经存在的孩子,例如,我想让leafnodes成为roottree的孩子 - > lastbranch - > lastleaf
我在闭包表中插入了两条新记录: (6-5)和(7-5)
然后一切都崩溃了。我已经尝试了所有我能想到的但是我没有到达任何地方。
答案 0 :(得分:0)
我在这里找到答案:Converting the Closure Table from a Weak Entity
ANSWER:我在闭包表中添加了两个字段来保存祖先和后代的id。现在节点独立于实际值。结构保持连接并用于插入,删除,查询等,但每个节点上保留的值是它们自己的实体,可以被任何其他实体替换,而不会影响树的结构。这使我能够解决我的特定问题,即在多个父类别中使用相同的子类别。我希望还有许多其他好处,还有待发现。