我面临着关于在项目中处理线程评论的决定...... 我有一个简单的MySQL表,其中包含所有注释。有两种类型:父母和孩子。孩子代表对父母或另一个孩子的回复。
我的问题:
- 成绩(深度0)
- 回复儿童(深度1)
---回复前一个孩子(深度2)
- 成绩(深度0)
想象一下上面的结构和带有LIMIT 2的MySQL查询。它将剪切最后一个回复(深度2)。其实我想说的是:尝试限制为2,如果孩子离开,直到下一个父母。尝试了几个没有运气的问题......
我现在所拥有的是如下:
选择
SQL_CALC_FOUND_ROWS
*
从
评论
哪里
comment_post_id ='{$ _REQUEST [“ID”]}'
订购
comment_id,comment_date
DESC LIMIT 10“
重要的表格字段是:
comment_id(index)| comment_parent_id(包含parent的comment_id或NULL)| comment_date
我会非常感谢任何想法!
Saludos, Booosh
答案 0 :(得分:1)
MySQL没有任何解析树状结构的函数。在最简单的场景中(子节点具有父节点的ID),您需要以编程方式递归到树中以定位给定节点的所有子节点。 MaxLevel表示您要去的深度。它会随着每次递归调用而递减,以便在结束时最终得到0,这会停止递归。
e.g。 (伪代码)
findNodes(String parentId, int maxLevel)
{
select * from posts where parent = parentId
foreach (result...)
{
if (maxLevel > 0)
{
findNodes(result.nodeId, maxLevel - 1)
}
doSomethingWIthAResult
}
}
为了以更简洁的方式执行此操作,有许多技术,所有这些技术都涉及某种索引字段,其中包含当前帖子的路径。路径看起来像这样:TopNode:Child1:Child2:Child3 ...你可以在这里做一个像这样的选择 从帖子中选择*,其中路径如“TopNode%”和depth = 2。
答案 1 :(得分:1)
总是考虑一下你真正想问问数据库的问题,然后将其翻译成SQL - 在这种情况下,你想要“与他们的直接孩子一起列出所有顶级评论,如果有的话”
例如。 (简化的)
SELECT * FROM comments c1
LEFT JOIN comments c2 ON c2.parent_comment_id=c1.comment_id
WHERE c1.parent_comment_id IS NULL
ORDER BY c1.comment_date, c1.comment_id, c2.comment_date, c2.comment_id;
有了这个结果,你可以按正确的顺序写出来 - 如果c2.comment_id为null,它是没有孩子的顶级评论,如果重复c1.comment_id,那么它是同一评论的另一个孩子。
答案 2 :(得分:1)
我遇到了同样的问题,只是我只走了一个深度。
--Comment (depth: 0)
---Reply (depth: 1)
我设法使用单个查询来选择所有这些记录,同时将顶级Comment
记录限制为仅10个。
SELECT c.* FROM comments AS c WHERE c.OwnerId = 1 AND c.ParentId = 0 LIMIT 10
UNION
SELECT cc.* FROM comments AS cc
INNER JOIN
(
SELECT CommentId FROM comments WHERE OwnerId = 1 AND ParentId = 0 LIMIT 10
)
AS c2
ON cc.ParentId = c2.CommentId
此查询基本上执行以下操作:
虽然,我认为这个查询比为每条记录多次调用数据库更有效,但它仍然存在执行第一次查询两次的缺陷。一次在工会之前,一次在工会的加入。
它似乎相当快,但没有我想要的那么快。但是,如果您的数据库是远程的,并且延迟是一个问题,那么此解决方案可能比为数据库进行多个远程查询更好。
答案 3 :(得分:0)
我终于根据Greg Adamskis暗示来管理它......所以不要投我的答案,但要检查一下!!!
简要描述问题...我们需要在我们的网站上对评论列表进行分页。使用标准限制可能会导致某些注释永远不会显示...我们需要的是一个限制,它只会影响我们的父节点,而不会影响回复的cild节点...很长的故事...但是有一次这个iis很有用对于某人:
function getComments($comment_parent_id, $scope,&$comments, $db)
{
$res = $db->select("SELECT * FROM comments WHERE comment_post_id = '{$_REQUEST["ID"]}' AND comment_parent_id = '{$comment_parent_id}' ORDER BY comment_date DESC LIMIT {$scope}");
while ($row = mysql_fetch_array($res, MYSQL_ASSOC))
{
$i = count($comments)+1;
foreach ($row as $k => $v) {
$comments[$i][$k] = $v;
}
//LOOK FOR REPLIES (childs of parent)
if (mysql_num_rows($db->select("SELECT * FROM comments WHERE comment_parent_id = '{$row['comment_id']}' LIMIT 1")) != 0 ){
getComments($row['comment_id'],100,$comments,$db);
}
}
}
//ARGUMENTS: parent_id (always starting with zero), scope, array holding comments, db class
getComments(0,5,$comments,$db);