节点方法MySql无限分类数据结构节点方法

最近研究节点方法,微稍总结一下,以后续继补充:

    限无类分是我们发开中非常见常的应用,像论坛的的版块,CMS的别类,应用的地方别特多。
我们最见常最简略的方法就是在MySql里ID ,parentID,name。其点优是简略,构结简略;点缺是效率不高,因为每一次递归都要查询数据库,几百条数据时就不是很快了!

存储树是一种见常的问题,多种解决方案。主要有两种方法:邻接表的型模,并修改树前序遍历算法。 

我们将探究这两种方法的节能级等的数据。我会应用树从一个虚拟的网上品食市肆作为一个例子。这品食市肆组织其品食类,通过颜色和类型。这棵树看起来像这样: 

    

    
面下我们将用另外一种方法,这就是预排序遍历树算法(modified preorder tree traversal algorithm) 
这类方法大家可能触接的比较少,首次应用也不像面上的方法易容解理,但是由于这类方法不应用递归查询算法,有更高的查询效率。
我们首先将多级数据按照面下的方法画在纸上,在根节点Food的侧左写上 1 然后沿着这个树续继向下 在 Fruit 的侧左写上 2 然后续继前进,沿着个整树的边缘给每个节点都标上侧左和右边的数字。最后一个数字是标在Food 右边的 18。 在面下的这张图中你可以看到个整标好了数字的多级构结。(没有看懂?用你的手指指着数字从1数到18就明确怎么回事了。还不明确,再数一遍,注意动移你的手指)。 
这些数字标明白各个节点之间的关系,"Red"的号是3和6,它是 "Food" 1-18 的孙子节点。 样同,我们可以看到 全部左值大于2和右值小于11的节点 都是"Fruit" 2-11 的孙子节点 

如图所示:

    


这样个整树状构结可以通过阁下值来存储到数据库中。续继之前,我们看一看面下整理过的数据表。 

    

    
注意:由于"left"和"right"在 SQL中有特别的意思,所以我们要需用"lft"和"rgt"来示表阁下段字。 另外这类构结中不再要需"parent"段字来示表树状构结。也就是 说面下这样的表构结就足够了。 

    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;

    

    
看到了吧,只要一个查询以可就失掉全部这些节点。为了可以像面上的递归函数那样表现个整树状构结,我们还要需对这样的查询停止排序。用节点的左值停止排序: 

    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;

    那么某个节点到底有多少孙子节点呢?很简略,孙子总数=(右值-左值-1)/2 
descendants = (right – left - 1) / 2 ,如果不是很楚清这个公式,那就去翻下书,我们在上数据构结写的很楚清!

加添统一层次的节点的方法如下:

    

LOCK  TABLE  nested_category WRITE;


SELECT   @myRight  : =  rgt  FROM  nested_category
WHERE  name  =   ' Cherry ' ;



UPDATE  nested_category  SET  rgt  =  rgt  +   2   WHERE  rgt  >   @myRight ;
UPDATE  nested_category  SET  lft  =  lft  +   2   WHERE  lft  >   @myRight ;

INSERT   INTO  nested_category(name, lft, rgt)  VALUES ( ' Strawberry ' ,  @myRight   +   1 ,  @myRight   +   2 );

UNLOCK TABLES;

    
加添树的子节点的方法如下:

    

LOCK  TABLE  nested_category WRITE;

SELECT   @myLeft  : =  lft  FROM  nested_category

WHERE  name  =   ' Beef ' ;

UPDATE  nested_category  SET  rgt  =  rgt  +   2   WHERE  rgt  >   @myLeft ;
UPDATE  nested_category  SET  lft  =  lft  +   2   WHERE  lft  >   @myLeft ;

INSERT   INTO  nested_category(name, lft, rgt)  VALUES ( ' charqui ' ,  @myLeft   +   1 ,  @myLeft   +   2 );

UNLOCK TABLES;

    每日一道理
共和国迎来了她五十诞辰。五十年像一条长河,有急流也有缓流;五十年像一幅长卷,有冷色也有暖色;五十年像一首乐曲,有低音也有高音;五十年像一部史诗,有痛苦也有欢乐。长河永远奔流,画卷刚刚展开,乐曲渐趋高潮,史诗还在续写。我们的共和国正迈着坚定的步伐,跨入新时代。

    
每次插入节点以后都可以用以下SQL停止查看验证:

    

SELECT  CONCAT( REPEAT(  '   ' , ( COUNT (parent.name)  -   1 ) ), node.name)  AS  name
FROM  nested_category  AS  node,
nested_category  AS  parent
WHERE  node.lft  BETWEEN  parent.lft  AND  parent.rgt
GROUP   BY  node.name
ORDER   BY  node.lft;

    
除删节点的方法,微稍有点烦麻是有个间中量变,如下:

    

LOCK  TABLE  nested_category WRITE;


SELECT   @myLeft  : =  lft,  @myRight  : =  rgt,  @myWidth  : =  rgt  -  lft  +   1
FROM  nested_category
WHERE  name  =   ' Cherry ' ;


DELETE   FROM  nested_category  WHERE  lft  BETWEEN   @myLeft   AND   @myRight ;


UPDATE  nested_category  SET  rgt  =  rgt  -   @myWidth   WHERE  rgt  >   @myRight ;
UPDATE  nested_category  SET  lft  =  lft  -   @myWidth   WHERE  lft  >   @myRight ;

UNLOCK TABLES;

 

    这类方法就是有点难的解理,但是合适数据量很大模规应用,查看全部的构结只要需两条SQL句语以可就了,在加添节点和除删节点的时候略显烦麻,不过相对效率说来还是值得的,此次现发让我现发了数据库构结真的很用有,但是我在黉舍学的树基本上都忘记了,此次碰到这个问题才应用到项目中!

考参文章:
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

    http://www.sitepoint.com/article/hierarchical-data-database/3/

 

文章结束给大家分享下程序员的一些笑话语录: 那是习惯决定的,一直保持一个习惯是不好的!IE6的用户不习惯多标签,但是最终肯定还是得转到多标签的浏览器。历史(软件UI)的进步(改善)不是以个人意志(习惯)为转移的!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值