【问题标题】:Implementing Recursive Comments in PHP/MySQL在 PHP/MySQL 中实现递归注释
【发布时间】:2012-03-29 15:15:14
【问题描述】:

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

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

【问题讨论】:

    标签: php mysql recursion


    【解决方案1】:

    尝试使用嵌套集合模型。在Managing Hierarchical Data in MySQL 中有描述。

    最大的好处是您不必使用递归来检索子节点,而且查询非常简单。缺点是插入和删除需要更多的工作。

    它的扩展性也非常好。我知道一个非常庞大的系统,它使用这种方法存储讨论层次结构。

    【讨论】:

      【解决方案2】:

      这里是another site,提供有关该方法的信息 + 一些源代码。

      【讨论】:

        【解决方案3】:

        这只是一个建议,但由于我现在面临同样的问题, 在 cmets 表中添加一个序列字段(int)和一个深度字段怎么样, 并在插入新的 cmets 时对其进行更新。

        序列字段将用于对 cme​​ts 进行排序。 深度场将指示评论的递归级别。

        那么困难的部分是在用户插入新 cmets 时进行正确的更新。

        我还不知道实现起来有多难, 但我很确定一旦实施,我们将获得基于嵌套模型的性能提升 解决方案。

        【讨论】:

          【解决方案4】:

          我创建了一个小教程来解释递归方法背后的基本概念。正如人们在上面所说的,递归函数也不能扩展,但是,插入的效率要高得多。

          以下是链接:

          http://www.evanpetersen.com/index.php/item/php-and-mysql-recursion.html

          http://www.evanpetersen.com/index.php/item/php-mysql-revisited.html

          【讨论】:

            【解决方案5】:

            我通常使用父子系统。

            例如,考虑以下情况:

            表格注释( 评论ID, 页面ID, 用户身份, 评论 [,父母ID] )

            parentID 是commentID(来自同一个表)的外键,它是可选的(可以是NULL)。

            对于选择 cmets,使用它作为“根”注释:

            SELECT * FROM comments WHERE pageID=:pageid AND parentID IS NULL
            

            这是给孩子的:

            SELECT * FROM comments WHERE pageID=:pageid AND parentID=:parentid
            

            【讨论】:

            • 但是如果孩子有孩子,他们有孩子,或者有很多cmets怎么办?这种方法似乎需要进行大量查询,并且当存在大量 cmets 时可能会变得非常慢。
            【解决方案6】:

            我也必须实现递归 cmets。 我用嵌套模型打破了我的头,让我解释一下原因:

            假设您想要一篇文章的 cmets。 我们将直接附在本文中的 cmets 称为 root cmets。 让我们调用回复 cmets 作为对另一个评论的回答的 cmets。

            我注意到(不幸的是)我希望根 cmets 按日期 desc 排序, 但我希望回复 cmets 被订购日期 asc ! 悖论!!

            所以嵌套模型并没有帮助我减少查询次数。

            这是我的解决方案:

            创建一个包含以下字段的评论表:

            身份证
            article_id
            parent_id(可为空)
            日期创作
            电子邮件
            随心所欲
            顺序
            深度

            这个实现的 3 个关键字段是 parent_id、sequence 和 depth。 parent_id 和 depth 有助于插入新节点。

            序列是真正的关键字段,它是一种嵌套模型模拟。

            每次插入新的根注释时,它都是 x 的倍数。 我选择 x=1000,这基本上意味着我最多可以有 1000 个嵌套 cmets(这是我发现的唯一缺点 对于这个系统,但是这个限制可以很容易地修改,现在已经足够我的需要了)。

            最近的根评论必须是具有最大序列号的评论。

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

            在这两种情况下,算法是相同的: 获取父母的序列,并检索一个以获取您的序列号。 然后你必须更新低于父序列和高于基本序列的序列号, 这是相关根注释正下方的根注释的顺序。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-10-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-09-06
              • 1970-01-01
              相关资源
              最近更新 更多