我正在尝试编写评论系统,人们可以在其中评论其他评论,并在页面上显示为递归线程。 (Reddit's评论系统是我正在努力实现的一个例子),但是我对如何实现这样一个不会很慢且计算量很大的系统感到困惑。
我想每个注释都会存储在注释表中,并包含一个parent_id,它将是另一个注释的外键。我的问题在于如何在没有大量查询的情况下获取所有这些数据,然后如何有效地将注释组织到订单中。有没有人对如何最好地实现这一点有任何想法?
答案 0 :(得分:5)
尝试使用嵌套集模型。它在Managing Hierarchical Data in MySQL中描述。
最大的好处是您不必使用递归来检索子节点,并且查询非常简单。缺点是插入和删除需要更多的工作。
它也很好地扩展。我知道一个非常庞大的系统,它使用这种方法存储讨论层次结构。
答案 1 :(得分:1)
这里是another site提供有关该方法的信息+一些源代码。
答案 2 :(得分:1)
我正常使用亲子系统。
例如,请考虑以下事项:
表评论( commentID, 的pageID, 用户身份, 评论 [,parentID] )
parentID是commentID(来自同一个表)的外键,它是可选的(可以是NULL)。
选择评论时,请将此用作“根”评论:
SELECT * FROM comments WHERE pageID=:pageid AND parentID IS NULL
这对于一个孩子来说:
SELECT * FROM comments WHERE pageID=:pageid AND parentID=:parentid
答案 3 :(得分:1)
我创建了一个小教程,解释了递归方法背后的基本概念。正如人们上面所说的那样,递归函数也没有扩展,但插入效率要高得多。
以下是链接:
http://www.evanpetersen.com/index.php/item/php-and-mysql-recursion.html
和
http://www.evanpetersen.com/index.php/item/php-mysql-revisited.html
答案 4 :(得分:1)
这只是一个建议,但由于我现在面临同样的问题, 如何在注释表中添加序列字段(int)和深度字段, 并在插入新评论时更新它。
序列字段用于排序注释的目的。 深度字段将指示评论的递归级别。
然后,当用户插入新评论时,困难部分将进行正确的更新。
我不知道这有多难实现, 但我很确定一旦实现,我们将比基于嵌套模型的性能提升 的解决方案。
答案 5 :(得分:1)
我也必须实现递归评论。 我用嵌套模型打破了我的头,让我解释一下原因:
假设你想要一篇文章评论。 让我们将根评论称为直接附于本文的评论。 让我们将回复评论的评论作为另一条评论的答案。
我注意到(不幸的是)我希望根据日期desc订购根评论, 但我希望回复评论是订购日期asc !! 悖论!!
因此,嵌套模型无法帮助我减轻查询次数。
这是我的解决方案:
使用以下字段创建评论表:
ID
article_id的
parent_id(可空)
date_creation
电子邮件
whateverYouLike
序列
深度
此实现的3个关键字段是parent_id,sequence和depth。 parent_id和depth有助于插入新节点。
序列是真正的关键字段,它是一种嵌套模型仿真。
每次插入新的根评论时,它都是x的倍数。 我选择x = 1000,这基本上意味着我可以拥有1000个最大嵌套注释(这是我发现的唯一缺点 对于这个系统,但这个限制可以很容易地修改,现在已足够我的需要了。)
最新的根评论必须是序列号最大的评论。
现在回复评论: 我们有两种情况: 回复根评论,或回复回复评论。
在这两种情况下,算法都是一样的: 取父母的序列,并检索一个以获取序列号。 然后你必须更新父序列之下和碱基序列之上的序列号, 这是有关根评论正下方的根评论序列。
我不希望你理解这一切,因为我不是一个很好的解释者, 但我希望它可能会给你新的想法。 (至少它对我来说比嵌套模型更好吗=更少的请求才是真正的目标)。