我有一个我写回来的脚本用于评论,但它只是单线程。我希望它是多线程的,但只有这样用户才能回复评论,而不是用户可以回复评论的评论。所以线程只有两个深度。
目前,我在我的数据库中对comment_id
存储user_id
。
我能想到做多线程注释的唯一方法是在comments表中有一个parent
字段。但是如果我这样做,那么当我用PHP选择注释时,我将不得不执行另一个SELECT命令来为每个注释选择注释子项(如果有的话)。似乎在数据库上做了很多工作。
必须有更好的方法。有什么想法吗?还是教程?
答案 0 :(得分:16)
有三种(四种)替代可能性:
递归查询,根据其父ID选择所有评论。许多数据库产品都支持此功能,语法取决于数据库类型。查看文档以获取更多信息(搜索“递归”)。
如果您在每个(子)评论中存储文章ID ,则只需在一个常规选择查询中选择包含文章ID的所有评论。您可以使用父ID在右侧父评论下正确显示页面上的评论:
SELECT * FROM comments WHERE article_id = :article_id
如果您只需要两个级别的评论,则可以使用扩展的其中来包含第一级和第二级评论:
SELECT * FROM comments
WHERE parent_id = :article_id
OR parent_id IN (SELECT id FROM comments WHERE parent_id = :article_id)
也可以使用 union all 来组合两个具有相同列的查询,但由于我假设所有数据都来自同一个表,因此可能不需要它(见上面扩展的where子句):
SELECT * FROM comments WHERE parent_id = :article_id
UNION ALL
SELECT * FROM comments WHERE parent_id IN
(SELECT id FROM comments WHERE parent_id = :article_id)
就个人而言,我会选择2,因为它很简单(不需要异乎寻常的SQL构造),高效(1个查询)和灵活(支持任意级别的注释)。
答案 1 :(得分:2)
1个查询就足够了,您只需要循环数据并将其正确存储到数组中,然后循环数组并显示注释。
答案 2 :(得分:2)
这是分层结构或树结构数据的常见用途。我写了一个关于Stack Overflow问题的流行答案:What is the most efficient/elegant way to parse a flat table into a tree?
我还写了一篇介绍树形结构数据替代方案的演示文稿:Models for Hierarchical Data with SQL and PHP。
我的演示文稿中未包含的另一个解决方案是Slashdot执行线程注释的方式。他们像您一样使用parent
列,因此每条评论都会引用它回复的评论。但是它们还包含root
列,因此每个评论都知道它所属的帖子。在给定的帖子上很少有超过几百条评论,通常你想从评论主题的顶部开始给出给定帖子的整个评论树:
SELECT * FROM comments WHERE root = 1234;
然后,当您获取注释时,您可以编写PHP代码,根据parent
列将它们处理为数组数组(这是@JanL的答案所提到的)。我在我对另一个Stack Overflow问题Convert flat array to the multi-dimentional的回答中发布了代码来执行此操作。
答案 3 :(得分:1)
此查询可能适合您(我不知道您的结构,所以我猜对了):
SELECT * FROM comments a
LEFT JOIN comments b ON a.comment_id = b.parent_coment_id
LEFT JOIN comments c ON b.comment_id = c.parent_coment_id
WHERE a.comment_id <> b.comment_id
AND a.comment_id <> c.comment_id
AND b.comment_id <> c.comment_id;