最近研究节点方法,微稍总结一下,以后续继补充:
限无类分是我们发开中非常见常的应用,像论坛的的版块,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 ,如果不是很楚清这个公式,那就去翻下书,我们在上数据构结写的很楚清!
加添统一层次的节点的方法如下:
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;
加添树的子节点的方法如下:
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停止查看验证:
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;
除删节点的方法,微稍有点烦麻是有个间中量变,如下:
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)的进步(改善)不是以个人意志(习惯)为转移的!