我正在开发一个网站,用户可以发布评论并对每条评论进行分类。我有一个页面,用户可以在该页面上查看网站上所有类别的列表,其中包含最新的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,它只会限制回复了评论的内容。
答案 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>
这样您就可以将代码移动到更有条理的结构中。