任何人都可以为线程评论系统建议一个创意数据库结构+获取算法,每个页面输出x个线程数(每个页面都有无限回复)?
我可以运行查询来获取线程,并在循环的每个实例中运行另一个查询以回显回复....但这是一个坏主意。
答案 0 :(得分:3)
如果您只需要2个级别,则可以使用一个查询:
您的表格 - id, parent_id, comment
列
<强>代码强>
$rows = mysql_query('
select *
FROM
comments
ORDER BY
id DESC');
$threads = array();
foreach($rows as $row) {
if($row['parent_id'] === '0') {
$threads[$row['id']] = array(
'comment' => $row['comment'],
'replies' => array()
);
} else {
$threads[$row['parent_id']]['replies'][] = $row['comment'];
}
}
在$threads
中,您将拥有所有主要帖子,$threads[$id]['replies']
包含所有回复。线程被排序 - 最新=首先,添加一些分页,你很高兴。
答案 1 :(得分:1)
在注释表中添加两列:parentCommentId和rootCommentId。
parentCommentId是父注释的id,rootCommentId是启动此线程的注释的id。
要显示N个线程,您需要两个查询:
(您可以将这两者合并为一个GroupBy查询。)
答案 2 :(得分:0)
刚刚遇到这个问题并且不得不解决它,我会在这里添加一个答案。一般问题是带有回复的评论是一个树排序问题,关系数据库不太适合这个问题。然而,评论数据库确实有一个非常有用的功能——它们按顺序排列,回复总是在他们回答的评论之后。这允许一个相当简单的程序化解决方案;首先选择评论并将它们保存到按 id 排序的数组中,然后通过数组添加字段“thread”和“threadbase”,其中 threadbase 是原始评论的 id(例如 0045),thread 是回复的路径(例如0045/0050/0120)。为此,给定一组带有 id 和 reply_to 字段的注释,php 是:
uasort($comments, fnMakeComparer(['id', SORT_ASC]));
$keys=array_keys($comments);
//go through the comments adding thread and threadbase
$n=count($comments);
for($x=0;$x<$n;$x++){
$key=$keys[$x];
$replyto=$comments[$key]['reply_to'];
$comments[$key]['thread']=$comments[$replyto]['thread']."/".$comments[$key]['id'];
$comments[$key]['threadbase']=substr($comments[$key]['thread'],0,6);
}
//resort comments by threadbase (most recent first) then thread (oldest first)
uasort($comments, fnMakeComparer((['threadbase', SORT_DESC]),['thread', SORT_ASC]),);
答案 3 :(得分:-1)
这类似于我现在使用的东西。唯一棘手的部分是在有人回复评论时计算要插入的下一个回复路径。
示例数据
ID | Comment | Path
---+------------------------------+----------
0 | Comment #1 | 01
1 | Comment #1 reply | 01_01
2 | Comment #1 reply reply | 01_01_01
3 | Comment #1 reply reply | 01_01_02
4 | Comment #2 | 02
5 | Comment #3 | 03
6 | Comment #3 reply | 03_01
示例SQL
SELECT * FROM comments ORDER BY path
示例PHP
while ($result = mysql_fetch_assoc($query)) {
$nesting_depth = count(explode("_", $result['path']));
$branch = str_repeat("--", $nesting_depth);
echo $branch {$result['comment']}";
}
示例结果
Comment #1
-- Comment #1 reply
---- Comment #1 reply reply
---- Comment #1 reply reply
Comment #2
Comment #3
-- Comment #3 reply
回复01_01
SELECT path FROM comments WHERE path LIKE '01\_01\___'
$last_path = $row[0];
$last_path_suffix = substr($last_path,strrpos($last_path,'_')+1);
$next_path_suffix = str_pad($last_path_suffix+1,2,'0',STR_PAD_LEFT);
$next_path = substr($last_path,0,strlen($last_path)-strlen($last_path_suffix)).$next_path_suffix;