分层评论的实现思路,thread comments 实现思路,数据库存树状结构
By:Roy.LiuLast updated:2012-09-16
用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 语句的话会是这样:
结果会如下:
事实上,数据库中的数据,会因为删除,增加变得顺序错乱,所以正常情况下,SQL语句会排序的
到节点的路径
由已知的节点,找到节点的路径,得到所有祖先的节点. 在数据表中,可以发现,比如 Cherry 节点,lft 的值应该小于4,而 rgt 的值应该大于5,要得到所以祖先,可以用如下SQL 语句
得到结果
+-------+
| 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.
现在插入新数据
这只是一个算法思想,具体的可以根据这个去实现.
因为不能满足自己的需要,所以就想做一个 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';
这只是一个算法思想,具体的可以根据这个去实现.
From:一号门
Previous:python读写配置文件
Next:django 应用执行定时任务
COMMENTS