在PHP / MySQL中实现递归注释

时间:2010-02-28 20:30:32

标签: php mysql recursion

我正在尝试编写评论系统,人们可以在其中评论其他评论,并在页面上显示为递归线程。 (Reddit's评论系统是我正在努力实现的一个例子),但是我对如何实现这样一个不会很慢且计算量很大的系统感到困惑。

我想每个注释都会存储在注释表中,并包含一个parent_id,它将是另一个注释的外键。我的问题在于如何在没有大量查询的情况下获取所有这些数据,然后如何有效地将注释组织到订单中。有没有人对如何最好地实现这一点有任何想法?

6 个答案:

答案 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个最大嵌套注释(这是我发现的唯一缺点 对于这个系统,但这个限制可以很容易地修改,现在已足够我的需要了。)

最新的根评论必须是序列号最大的评论。

现在回复评论: 我们有两种情况: 回复根评论,或回复回复评论。

在这两种情况下,算法都是一样的: 取父母的序列,并检索一个以获取序列号。 然后你必须更新父序列之下和碱基序列之上的序列号, 这是有关根评论正下方的根评论序列。

我不希望你理解这一切,因为我不是一个很好的解释者, 但我希望它可能会给你新的想法。 (至少它对我来说比嵌套模型更好吗=更少的请求才是真正的目标)。