使用MYSQL列出包含最新评论/活动的类别

时间:2009-08-05 11:04:55

标签: php mysql

我正在开发一个网站,用户可以发布评论并对每条评论进行分类。我有一个页面,用户可以在该页面上查看网站上所有类别的列表,其中包含最新的5条评论。

我需要从数据库中检索的信息是:

  • 类别列表
    • 每个类别中的5条评论

这就是我现在所拥有的(简化为基本的PHP):

echo "<ul>";
$query = mysql_query("SELECT * FROM categories");
while($result = mysql_fetch_assoc($query)){

    echo "<li><h2>{$result['category_name']}</h2>";

    $query_comments = mysql_query(
                                 "SELECT * FROM comments WHERE ".
                                 "category_id = '{$result['id']}' ".
                                 "ORDER BY created_at DESC LIMIT 5");
    while($result_comments = mysql_fetch_assoc($query_comments)){
        echo "{$result_comments['username']} wrote {$result_comments['text']} on {$result_comments['created_at']}<br>";
    }

    echo "</li>";

}
echo "</ul>";

看起来像这样(假设我的类别是水果名称)

Apple
    Jay wrote blah blah blah - August 5, 2009
    Bob wrote hello hello hello - August 5, 2009
    Tom wrote super super - August 5, 2009
    Edward wrote no no no - August 5, 2009
    Kaysie wrote super no! - August 5, 2009

Orange
    Cassie wrote ye ye ye ye - August 5, 2009
    Alfonce wrote whoohoo - August 5, 2009
    Arthur wrote love oranges - August 5, 2009
    Alice wrote yes yes yes - August 5, 2009
    Xavier wrote Lorem ipsum dolor sit amet - August 5, 2009

Strawberry
    Chris wrote Lorem ipsum dolor sit amet - August 5, 2009
    Hubert wrote Lorem ipsum dolor sit amet - August 5, 2009
    Martin wrote Lorem ipsum dolor sit amet - August 5, 2009
    Lyon wrote Lorem ipsum dolor sit amet - August 5, 2009
    Paris wrote Lorem ipsum dolor sit amet - August 5, 2009

Blueberry
    etc...

问题是,如果有很多类别,我会遇到性能问题,特别是如果有很多用户使用该网站。

我正在努力寻找减少所需查询量的方法。有没有人知道我该怎么做?

更新我尝试使用评论表LEFT JOIN类别表但是,我没有找到限制每个类别的评论数量的方法,因为如果我使用LIMIT 5,它只会限制回复了评论的内容。

4 个答案:

答案 0 :(得分:2)

我和一个数据库人谈过,结果证明MySQL有点痛苦。

这样的东西在PostgreSQL中会很好用:

SELECT * FROM categories
LEFT JOIN comments ON categories.id = comments.category_id
WHERE comments.id IS NULL OR
comments.id IN ( SELECT id FROM comments AS a2 WHERE categories.id = a2.category_id ORDER BY id DESC LIMIT 5 )

不幸的是MySQL不支持子查询中的LIMIT。他挠了挠头说有一个可用的解决方法,但听起来不太好听。那时我想你也可以使用多个查询。如果这是性能问题,则可能是您暂时缓存的数据。

抱歉,帮助不大:)

错误的答案:尝试在查询中使用LEFT JOIN,左侧是类别(因此无论是否有评论,都会返回所有类别)和右侧的评论表。这会将其减少为一个查询。

答案 1 :(得分:2)

您可以使用加入:

SELECT categories.category_name, comments.*
FROM comments 
LEFT JOIN categories ON categories.category_id=comments.category_id

并改变迭代结果的方式。

答案 2 :(得分:0)

也许是这样的事情?

SELECT cat.*, com.*
FROM categories cat, comments com
WHERE com.categoryid=cat.id
ORDER BY cat.category_name ASC, com.created_at DESC

注意:扩展*以仅选择您需要的内容(并消除任何歧义的可能性)会更明智。

编辑:在仔细阅读之后,我认为你不想要这个或任何其他答案,因为它会抓住数据库中的每一条评论,而不仅仅是最新评论。

我现在能想到的最佳解决方案是让您选择多久以前可以忽略,并添加com.created_at > [date]以限制所选评论的总数。这可能意味着某些类别即使用户已经制作了5个或更多,但很久以前也没有显示5条评论。

答案 3 :(得分:0)

我看不到你的所有代码,但我真的认为你应该创建一个函数

get_categories()
{
    //PSEUDO: $results_array;
    //PSEUDO: return $results_array = mysql_results;
}

如果您有时间,我建议您迁移到PDO

您的HTML将是:

// rough PSEUDO Code
<ui>
    <li>
         <?php 
             foreach ($results_array as $key => $value)
             {
                 echo(htmlentitites($value);
             }
         ?>

    </li>


</ui>

这样您就可以将代码移动到更有条理的结构中。