数据库树状结构构建

现在需要存储下面tree的结构

数据库树状结构构建_第1张图片

通常我们会设计节点之间的继承关系:

数据库树状结构构建_第2张图片

这种设计简单方便,但是由于节点之间的继承关系,对tree的crud操作都比较低效,主要是因为频繁的递归的操作

基于左右值的设计

create table `node`(
	`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
	`name` varchar(20) NOT NULL COMMENT '节点名',
	`lft` int unsigned NOT NULL COMMENT '左边值',
	`rgt` int unsigned NOT NULL COMMENT '右边值',
	PRIMARY KEY(`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='树形结构';
插入:
insert into tree values(1,'Food',1,18)(2, 'Fruit', 2, 11),(3,'Red',3,6),(4,'Cherry',4,5),(5,'Yellow',7,10),(6,'Banana',8,9),(7,'Meat',12,17),(8,'Beef',13,14),(9,'Pork',15,16);
查看子节点
SELECT * FROM tree WHERE lft>2 AND lft<11 ORDER BY lft ASC;
查看当前节点层次
SELECT COUNT(*) FROM tree WHERE lft<=2 AND rgt>=11;
添加同一层次的节点
LOCK TABLE tree WRITE;
SELECT @myRight := rgt FROM tree WHERE name = 'Cherry';
UPDATE tree SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE tree SET lft = lft + 2 WHERE lft > @myRight;
INSERT INTO tree(name, lft, rgt) VALUES('Strawberry', @myRight + 1, @myRight + 2);
UNLOCK TABLES;
添加树的子节点的方法
LOCK TABLE tree WRITE;
SELECT @myLeft := lft FROM tree WHERE name = 'Beef';
UPDATE tree SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE tree SET lft = lft + 2 WHERE lft > @myLeft;
INSERT INTO tree(name, lft, rgt) VALUES('charqui', @myLeft + 1, @myLeft + 2);
UNLOCK TABLES;
插入节点之后都可以用以下SQL进行查看验证
SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM tree AS node,
tree AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
删除节点的方法,稍微有点麻烦是有个中间变量
LOCK TABLE tree WRITE;
SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM tree WHERE name = 'Cherry';
DELETE FROM tree WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE tree SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE tree SET lft = lft - @myWidth WHERE lft > @myRight;
UNLOCK TABLES;
//适合数据量很大规模使用,查看所有的结构只需要两条SQL语句就可以
 
  

数据结构图:

数据库树状结构构建_第3张图片

逻辑图:

数据库树状结构构建_第4张图片

对树形结构的CRUD操作:

  获取fruit时只需要执行: select * from tree where lft between 2 and 11 order by lft asc;

子孙数=(右值-左值-1)/2

查看节点所处于的层次: select count(*) from tree where lft<=2 and rgt>=11;


参考文章: http://blog.csdn.net/monkey_d_meng/article/details/6647488

SQL语句参考: http://my.oschina.net/XYleung/blog/99604

你可能感兴趣的:(Learn,mysql)