1

任何人都可以为线程评论系统建议一个创造性的数据库结构+获取算法,这将在每页输出 x 数量的线程(每个线程无限回复)?

我可以运行查询来获取线程,并在循环的每个实例中,运行另一个查询来回显回复......但这是个坏主意。

4

4 回答 4

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']保存所有回复。线程已排序 - 最新 = 首先,添加一些分页,您就可以开始了。

于 2009-09-20T21:07:13.140 回答
1

向评论表添加两列:parentCommentId 和 rootCommentId。

parentCommentId 是父评论的id,rootCommentId 是启动这个线程的评论的id。

要显示 N 个线程,您需要两个查询:

  1. 从rootCommentId = id的评论表中获取N行
  2. 获取这 N 个线程的所有评论

(您可以将这两者组合成一个 GroupBy 查询。)

于 2009-09-18T07:46:29.657 回答
0

这类似于我现在使用的东西。唯一棘手的部分是计算当有人回复评论时要插入的下一个回复路径。

示例数据

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;
于 2012-10-21T17:30:11.267 回答
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]),);

  
于 2021-02-12T12:37:56.747 回答