在PHP/MySQL中实现递归注解

bzzcjhmw  于 2022-10-22  发布在  PHP
关注(0)|答案(7)|浏览(114)

我正在尝试编写一个评论系统,人们可以在其中对其他评论进行评论,这些评论在页面上显示为递归线程。(Reddit's Commenting system是我尝试实现的一个例子),但是我对如何实现这样一个不太慢且计算成本不高的系统感到困惑。
我想象每个注解都将存储在注解表中,并包含一个parent_id,它将是另一个注解的外键。我的问题是如何在没有大量查询的情况下获得所有这些数据,然后如何高效地将注解组织到所属的顺序中。有人对如何最好地实现这一点有什么想法吗?

db2dz4w8

db2dz4w81#

尝试使用嵌套集合模型。这在Managing Hierarchical Data in MySQL中进行了描述。
最大的好处是您不必使用递归来检索子节点,而且查询非常简单。缺点是插入和删除需要更多的工作。
它的伸缩性也非常好。我知道有一个非常庞大的系统,它使用这种方法存储讨论层次结构。

vyswwuz2

vyswwuz22#

下面是another site提供的关于该方法的信息+一些源代码。

ac1kyiln

ac1kyiln3#

这只是一个建议,但既然我现在面临着同样的问题,那么在注解表中添加一个序列字段(int)和一个深度字段,并在插入新注解时更新它。
序列字段将用于对注解进行排序。深度字段将指示注解的递归级别。
然后,最困难的部分是在用户插入新评论时进行正确的更新。
我还不知道实现这有多困难,但我很确定一旦实现,我们将比基于嵌套模型的解决方案获得性能提升。

oewdyzsn

oewdyzsn4#

我创建了一个小教程,解释递归方法背后的基本概念。正如人们前面所说的,递归函数的伸缩性不好,但是,插入的效率要高得多。
以下是链接:
http://www.evanpetersen.com/index.php/item/php-and-mysql-recursion.html

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

sqougxex

sqougxex5#

我通常使用父子系统。
例如,考虑以下内容:
表注解(commentID,pageID,userID,comment[,parentID])
parentID是commentID的外键(来自同一个表),它是可选的(可以为NULL)。
要选择注解,请将其用作“根”注解:

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

对于一个孩子来说:

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

uklbhaso6#

我还必须实现递归注解。我用嵌套模型打破了我的脑袋,让我解释一下原因:
比方说,你想要一篇文章的评论。让我们把根评论称为直接附在本文后面的评论。让我们把回复评论称为对另一条评论的回复。
我注意到(不幸的是)我希望根评论按日期desc排序,但我希望回复评论按日期asc排序!!矛盾!!
所以嵌套模型并没有帮助我减少查询的数量。
以下是我的解决方案:
使用以下字段创建注解表:
身份证件
文章id
parent_id(可为空)
创建日期(_C)
电子邮件
你喜欢什么
序列
深度
这个实现的3个关键字段是parent_id、sequence和depth。parent_id和depth有助于插入新节点。
序列是真正的关键字段,它是一种嵌套模型仿真。
每次你插入一个新的根注解时,它是x的倍数。我选择x=1000,这基本上意味着我最多可以有1000个嵌套注解(这是我在这个系统中发现的唯一缺点,但这个限制可以很容易地修改,现在已经足够满足我的需要了)。
最近的根注解必须是序列号最大的根注解。
现在回复评论:我们有两种情况:回复根评论,或回复回复评论。
在这两种情况下,算法都是相同的:取父序列,然后检索一个以获得序列号。然后,您必须更新位于父序列下方和基序列上方的序列号,基序列是相关根注解下方的根注解序列。
我不希望你理解这一切,因为我不是一个很好的解释者,但我希望它能给你带来新的想法。(至少它比嵌套模型更适合我,这是真正的目标)。

nom7f22z

nom7f22z7#

我采取了一种简单的方法。

  • 保存根id(如果是注解,则为post_id)
  • 保存parent_id

然后使用post_id获取所有注解,并在客户端上递归排序。我不在乎是否有1000条评论。这发生在记忆中。
这是一次数据库调用,这是一个昂贵的部分。

相关问题