在你喊ORDER BY id
之前,情况就完全不同了。
我被要求制作的论坛是留言簿论坛,未注册的用户可以回复并发帖。在回复的帖子下缩进对帖子的回复。当然,这都是无序列表。一个简短的例子:
这就像Nettuts+的评论系统一样。在数据库中,帖子包含所有明显的东西(id,消息体,作者,时间......)和回复。 replyid基本上意味着这篇帖子的回复是什么。如果replyid为0,则它是主帖(普通论坛中的线程意味着。)
这就是我如何展示这些帖子:首先,我调用一个函数(让我们称之为showPosts),它有一个名为replyid的可选参数;默认为0。
在showPosts中,我在关联数组中使用等于数据库中param的所有帖子获取,并使用showPosts的结果填充数组中的posts
字段,并将show传递给showPosts这篇文章。在showPosts的最后,我返回那个关联数组。如果不清楚,这里是片段:
function showPosts($postid = 0) {
$query = query("SELECT * FROM posts WHERE replyid='$postid'");
$r = array();
$i = 0;
while (@$row = $query->fetch_assoc()) {
$r[$i] = $row;
$r[$i]['posts'] = showPosts($row['id']);
++$i;
}
return $r;
}
一切都很有效,就像预期的那样,但我被这个问题所困扰:当用户回复旧帖子时,我希望首先显示该帖子,就像你在论坛帖子中一样。
我已经考虑过在数据库中创建一个名为lastChanged的字段,每当用户发布新的回复时,它就会一直向上发布,并将每个lastChanged值更改为发布时间。然而,这似乎只是浪费记忆和可能的时间杀手。我还想过从回复中分离主线程,但这会让事情变得复杂一些,我喜欢在线程和帖子之间没有区别的美,因为任何东西都可以是一个线程或者是一个帖子。
您知道,数据库是用PHP编写的MySQL和后端(当然,使用MySQLi与MySQL进行交互。)
提前致谢,如果有什么不清楚,请抱歉。
编辑:db的结构,按要求。
id | int(11)
title | varchar(100)
author | varchar(100)
body | text
replyid | int(11)
time | datetime
答案 0 :(得分:0)
如果您不想使用lastChanged
您必须计算显示部分中最后一条评论的上一次(在您发布的PHP方法中),并且当您有父级帖子的最后修改日期时,您可以对php数组进行排序。 / p>
这个步行不会有任何好处,因为你已经有了递归,你只需要找出正确的方法来上传最后一个回复的日期并在最终返回之前对数组进行排序。
像这样(没有排序)
function getPost($postid = 0) {
$query = query("SELECT * FROM posts WHERE replyid='$postid'");
$r = array();
$i = 0;
$recenttime=0;
while (@$row = $query->fetch_array(MYSQLI_ASSOC)) {
$r[$i] = $row;
if (strtotime($row['time'])>$recenttime) {
$recenttime=strtotime($row['time']);
}
$r[$i]['posts'] = $this->getPost($row['id']);
if ($r[$i]['posts']['recenttime']>$recenttime) {
$recenttime=$r[$i]['posts']['recenttime'];
}
++$i;
}
$r['recenttime']=$recenttime;//save recenttime for this level
if ($postid == 0) {
// do the sort here based on $r[$i][$recenttime];
}
return $r;
}
答案 1 :(得分:0)
鉴于我和Zirak之间原始问题的评论,我提出以下答案。
他是对的 - 遍历整个树以找到最近评论的日期可能需要一段时间,因为看起来对系统中可能发生的嵌套级别没有限制。我知道这是很多重复的数据,但为什么不存储类似main_post_id
的东西,它指的是根节点(主帖)。这样你就可以ORDER BY max(time) WHERE main_post_id = 1
。
如果它是论坛软件(我假设它也可能涉及线程列表的分页等),那么这将使生活变得更容易,因为您可以在数据库查询级别而不是在PHP中执行排序
答案 2 :(得分:0)
嗯..考虑到阅读列表的执行频率远远超过写作。而且考虑到读取涉及更多数据,我宁愿将负载放在写入时间上。
使用rootC级别的lastChanged解决方案,您还可以使用简单的SQL查询读取少得多的行,而不是读取x行数。
Sams解决方案的缺点是,你需要一个额外的GROUP BY,它会导致一个临时表,这会降低你的sql服务器的速度。