閉包表記錄了樹中所有節點的關系,不僅僅只是直接父子關系,它需要使用2張表,除了節點表本身之外,還需要使用1張表來存儲節祖先點和后代節點之間的關系(同時增加一行節點指向自身),
並且根據需要,可以增加一個字段,表示深度。因此這種方法數據量很多。設計的表結構如下:
create table `node` (
`id` int(10) not null,
`name` varchar(50) default null,
primary key (`id`)
) engine=innodb default charset=utf8;
create table `tree_path` (
`anc` int(10) not null comment '祖先節點',
`des` int(10) not null comment '子孫節點',
`pc` int(1) default null comment '是否為父子節點 1/0',
primary key (`anc`,`des`)
) engine=innodb default charset=utf8;
-- 示例樹
-- root(0)
-- |
-- a(1)
-- |___a1(2)
-- |___a2(3)
-- b(4)
-- |___b1(5)
-- |___b2(6)
-- |___c(7)
-- |___c1(8)
-- |___d(9)
-- |___e(10)
insert into node(id,name) values (0,'root');
insert into node(id,name) values (1,'a');
insert into node(id,name) values (2,'a1');
insert into node(id,name) values (3,'a2');
insert into node(id,name) values (4,'b');
insert into node(id,name) values (5,'b1');
insert into node(id,name) values (6,'b2');
insert into node(id,name) values (7,'c');
insert into node(id,name) values (8,'c1');
insert into node(id,name) values (9,'d');
insert into node(id,name) values (10,'e');
insert into tree_path(anc,des,pc) values (0,1,1);
insert into tree_path(anc,des,pc) values (0,2,0);
insert into tree_path(anc,des,pc) values (0,3,0);
insert into tree_path(anc,des,pc) values (0,4,1);
insert into tree_path(anc,des,pc) values (0,5,0);
insert into tree_path(anc,des,pc) values (0,6,0);
insert into tree_path(anc,des,pc) values (0,7,0);
insert into tree_path(anc,des,pc) values (0,8,0);
insert into tree_path(anc,des,pc) values (0,9,0);
insert into tree_path(anc,des,pc) values (0,10,0);
insert into tree_path(anc,des,pc) values (1,1,0);
insert into tree_path(anc,des,pc) values (2,2,0);
insert into tree_path(anc,des,pc) values (3,3,0);
insert into tree_path(anc,des,pc) values (4,4,0);
insert into tree_path(anc,des,pc) values (5,5,0);
insert into tree_path(anc,des,pc) values (6,6,0);
insert into tree_path(anc,des,pc) values (7,7,0);
insert into tree_path(anc,des,pc) values (8,8,0);
insert into tree_path(anc,des,pc) values (9,9,0);
insert into tree_path(anc,des,pc) values (10,10,0);
insert into tree_path(anc,des,pc) values (1,2,1);
insert into tree_path(anc,des,pc) values (1,3,1);
insert into tree_path(anc,des,pc) values (4,5,1);
insert into tree_path(anc,des,pc) values (4,6,1);
insert into tree_path(anc,des,pc) values (4,7,1);
insert into tree_path(anc,des,pc) values (4,8,0);
insert into tree_path(anc,des,pc) values (4,9,0);
insert into tree_path(anc,des,pc) values (4,10,0);
insert into tree_path(anc,des,pc) values (7,8,1);
insert into tree_path(anc,des,pc) values (7,9,1);
insert into tree_path(anc,des,pc) values (7,10,0);
insert into tree_path(anc,des,pc) values (9,10,1);
刪除子樹
假設要刪除子樹#7
delete from tree_path
where tree_path.des in (select t.des from tree_path t where t.anc=7)
移動子樹
假設我們要把子樹#7從節點#4移動到節點#1
1.分離子樹,刪除子樹節點與其祖先的關系
delete from tree_path where tree_path.anc=7
2.將上一步分離出的子樹用笛卡爾積嫁接到#1下
select
super.anc,
sub.des,
case
when
super.anc=1 and sub.des=7 then 1
else 0
end pc
from
tree_path super
cross join
tree_path sub
where
super.des=1 and sub.anc=7
查詢樹形結構
xxxxxx