改进的前序遍历树模型(The Nested Set Model)
原理:
我们先把树按照水平方式摆开。从根节点开始(“Food”),然后他的左边写上1。然后按照树的顺序(从上到下)给“Fruit”的左边写上2。这样,你沿着树的边界走啊走(这就是“遍历”),然后同时在每个节点的左边和右边写上数字。最后,我们回到了根节点“Food”在右边写上18。下面是标上了数字的树,同时把遍历的顺序用箭头标出来了。
我们称这些数字为左值和右值(如,“Food”的左值是1,右值是18)。正如你所见,这些数字按时了每个节点之间的关系。因为“Red”有3和6两个值,所以,它是有拥有1-18值的“Food”节点的后续。同样的,我们可以推断所有左值大于2并且右值小于11的节点,都是有2-11的“Fruit” 节点的后续。这样,树的结构就通过左值和右值储存下来了。这种数遍整棵树算节点的方法叫做“改进前序遍历树”算法。
表结构设计:
常用的操作:
下面列出一些常用操作的SQL语句
返回完整的树(Retrieving a Full Tree)
SELECTnode.nameFROMnested_category node, nested_category parentWHEREnode.lftBETWEENparent.lftANDparent.rgtANDparent.name='electronics'ORDERBYnode.lft
返回某结点的子树(Find the Immediate Subordinates of a Node)
SELECTV.*FROM(SELECTnode.name,
(COUNT(parent.name)-(AVG(sub_tree.depth)+1)) depthFROMnested_category node,
nested_category parent,
nested_category sub_parent,
(SELECTV.*FROM(SELECTnode.name, (COUNT(parent.name)-1) depthFROMnested_category node, nested_category parentWHEREnode.lftBETWEENparent.lftANDparent.rgtANDnode.name='portable electronics'GROUPBYnode.name) V,
nested_category TWHEREV.name=T.nameORDERBYT.lft) sub_treeWHEREnode.lftBETWEENparent.lftANDparent.rgtANDnode.lftBETWEENsub_parent.lftANDsub_parent.rgtANDsub_parent.name=sub_tree.nameGROUPBYnode.name) V,
nested_category TWHEREV.name=T.nameandV.depth<=1andV.depth>0ORDERBYT.Lft
返回某结点的祖谱路径(Retrieving a Single Path)
SELECTparent.nameFROMnested_category node, nested_category parentWHEREnode.lftBETWEENparent.lftANDparent.rgtANDnode.name='flash'ORDERBYnode.lft
返回所有节点的深度(Finding the Depth of the Nodes)
SELECTV.*FROM(SELECTnode.name, (COUNT(parent.name)-1) depthFROMnested_category node, nested_category parentWHEREnode.lftBETWEENparent.lftANDparent.rgtGROUPBYnode.name) V,
nested_category TWHEREV.name=T.nameORDERBYT.Lft
返回子树的深度(Depth of a Sub-Tree)
SELECTV.*FROM(SELECTnode.name,
(COUNT(parent.name)-(AVG(sub_tree.depth)+1)) depthFROMnested_category node,
nested_category parent,
nested_category sub_parent,
(SELECTV.*FROM(SELECTnode.name, (COUNT(parent.name)-1) depthFROMnested_category node, nested_category parentWHEREnode.lftBETWEENparent.lftANDparent.rgtANDnode.name='portable electronics'GROUPBYnode.name) V,
nested_category TWHEREV.name=T.nameORDERBYT.lft) sub_treeWHEREnode.lftBETWEENparent.lftANDparent.rgtANDnode.lftBETWEENsub_parent.lftANDsub_parent.rgtANDsub_parent.name=sub_tree.nameGROUPBYnode.name) V,
nested_category TWHEREV.name=T.nameORDERBYT.Lft
返回所有的叶子节点(Finding all the Leaf Nodes)
SELECTnameFROMnested_categoryWHERErgt=lft+1
插入节点(Adding New Nodes)
LOCKTABLEnested_category WRITE;SELECT@myRight:=rgtFROMnested_categoryWHEREname='TELEVISIONS';UPDATEnested_categorySETrgt=rgt+2WHERErgt>@myRight;UPDATEnested_categorySETlft=lft+2WHERElft>@myRight;INSERTINTOnested_category
(name, lft, rgt)VALUES('GAME CONSOLES',@myRight+1,@myRight+2);
UNLOCK TABLES;
删除节点(Deleting Nodes)
LOCKTABLEnested_category WRITE;SELECT@myLeft:=lft,@myRight:=rgt,@myWidth:=rgt-lft+1FROMnested_categoryWHEREname='GAME CONSOLES';DELETEFROMnested_categoryWHERElftBETWEEN@myLeftAND@myRight;UPDATEnested_categorySETrgt=rgt-@myWidthWHERErgt>@myRight;UPDATEnested_categorySETlft=lft-@myWidthWHERElft>@myRight;
UNLOCK TABLES;
分享到:
2010-02-05 16:27
浏览 2058
评论