分层评论的实现思路,thread comments 实现思路,数据库存树状结构

用django 做了个小应用,最后需要做一个评论的东西。最好是树状结构,分层的。 django 本身有 comment这个 app ,但不支持分层的。个人觉得很不好用,也很不方便,如果真是类似 django 自带的 comment  自己实现一个是很轻松的事。跟不不用 comment  app.

因为不能满足自己的需要,所以就想做一个 thread comments. 虽然网上有 django thread comments  的下载,但还是想自己实现一个,今后好扩展。因为自己实现的,可以不拘泥于django框架。自己用原生态方法实现。

其实可以把评论当做一棵树来看,用类似于树的前序排列方法,应该可以实现这功能。记录一个大概的思路,虽然还没完全实现,但我会实现的。

比如有一棵树:从根节点(food) 开始,在他的左边写1,在他的子节点左边写 2,依次类推。沿着这棵树的边走下去,并在他的左边,右边都写上数字.....最后一个数字应该在根节点(food)的右边,如下图所示,沿着箭头的方向,看标记的数字。


你会发现,food 左边是数字 1,右边是数字 18,更重要的是,这些数字其实表明了这些节点之间的关系。你看到"Red" 的数字是3和6,他是 food 数字 1,18 的后代。再仔细一点,你会发现 左边数字大于2 右边数字小于 11 的都是 2-11(Fruit)的后代。现在这棵树其实就可以由左右数字保存下来。看一下在表中的数据.


字段名,没有直接用 left,right ,是因为这是数据库的保留字段,所以用了 lft, rgt 来表示。现在看来,其实parent 字段不是必须的,因为完全可以通 lft 和 rgt 来存储了树状结构

如何取数据
如果你想通过lft,rgt  来取数据的话,你先要确定,你想获取那一个节点。比如你要得到 Fruit  的子树。你仅仅需要找到 lft 在2和11之间的。用SQL 语句的话会是这样:
程序代码 程序代码

Select * FROM tree Where lft BETWEEN 2 AND 11;

结果会如下:

事实上,数据库中的数据,会因为删除,增加变得顺序错乱,所以正常情况下,SQL语句会排序的
程序代码 程序代码

Select * FROM tree Where lft BETWEEN 2 AND 11 orDER BY lft ASC;


到节点的路径
由已知的节点,找到节点的路径,得到所有祖先的节点. 在数据表中,可以发现,比如 Cherry 节点,lft 的值应该小于4,而 rgt 的值应该大于5,要得到所以祖先,可以用如下SQL 语句
程序代码 程序代码

Select title FROM tree Where lft < 4 AND rgt > 5 orDER BY lft ASC;  

得到结果
+-------+
| title |
+-------+
| Food  |
| Fruit  |
| Red   |
+-------+
把每一行 链接起来,你就得到路径了:Food--Fruit-Red 这就是到达 Cherry 的路径.

增加,删除一个节点
其实也就是通过更改节点的 lft ,rgt的值来实现。来看一个例子, 新增加一个水果  ”Strawberry",作为最后一个节点,同时也是 Red 的子节点.首先,应该将 Red 的right 的值应该从6改成8,Yellow  应该由7-10改成 9-12 等等。更改 Red 这个节点,意味着,需要对left和right  各自加上2.

程序代码 程序代码

Update tree SET rgt=rgt+2 Where rgt>5;
Update tree SET lft=lft+2 Where lft>5;

现在插入新数据
程序代码 程序代码

Insert INTO tree SET lft=6, rgt=7, title='Strawberry';  


这只是一个算法思想,具体的可以根据这个去实现.

除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
[本日志由 轻舞肥羊 于 2012-09-16 08:36 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: django comments
相关日志:
评论: 2 | 引用: 0 | 查看次数: -
回复回复111[2018-10-13 03:56 PM | del]
1111
回复回复轻舞肥羊[2012-09-16 08:46 PM | del]
其实可以用 链表方式,每个节点存储自己的父节点方式来实现,但取数据的时候,需要递归调用,数据量大时,性能不高。不如用树实现好。
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.