0

我正在做一个微博网站。用户可以互相关注。我必须根据当前用户关注的用户(如 Twitter)为当前用户( $userid )制作帖子流(活动流)。我知道实现这一点的两种方法。哪一个更好?

表:

表:帖子
列:PostID、AuthorID、TimeStamp、Content

表:关注
列:海报、关注者

一种方式,通过加入这两个表:

select `posts`.* from `posts`,`follow` where `follow`.`follower`='$userid' and 
`posts`.`AuthorID`=`follow`.`poster` order by `posts`.`postid` desc


第二种方法是通过创建一个用户数组 $userid 正在关注(海报),然后在这个数组上执行 php 内爆,然后在其中执行:

我想在这里告诉你的一件事是我正在存储数字用户在 `user` 表的 `following` 记录中关注的用户数,所以在这里我将使用这个数字作为提取海报列表时的限制 - 'followingList':

function followingList($userid){
    $listArray=array();
    $limit="select `following` from `users` where `userid`='$userid' limit 1";
    $limit=mysql_query($limit);
    $limit=mysql_fetch_row($limit);
    $limit= (int) $limit[0];
    $sql="select `poster` from `follow` where `follower`='$userid' limit $limit";
    $result=mysql_query($sql);
    while($data = mysql_fetch_row($result)){
        $listArray[] = $data[0];
    }
    $posters=implode("','",$listArray);
    return $posters;
}


现在,我有一个逗号分隔的用户 ID 列表,当前 $userid 正在遵循该列表。

现在选择帖子以制作活动流:

$posters=followingList($userid);
$sql = "select * from `posts` where (`AuthorID` in ('$posters')) 
order by `postid` desc";


这两种方法哪个更好?并且可以知道关注的总数(当前用户关注的用户数量),在第一种方法中使事情变得更快,就像在第二种方法中一样?
还有其他更好的方法吗?

4

2 回答 2

3

您应该一直使用第一个选项。始终尽可能多地尝试在 mysql 服务器上而不是在您的 PHP 代码中处理数据。PHP 不会隐式缓存操作的结果,而 MySQL 会这样做。

最重要的是确保正确索引数据。尝试使用“EXPLAIN”语句以确保您已尽可能优化数据库并使用#1 将您的数据链接在一起。

http://dev.mysql.com/doc/refman/5.0/en/explain.html

这也将允许您稍后计算统计信息,而第二种方法需要您处理部分统计信息。

于 2012-07-24T15:11:21.137 回答
1

第一个重要的一点是,PHP 擅长构建页面,但非常糟糕的是管理数据,PHP 操作的所有内容都会填满内存,并且 PHP 中不能应用任何特殊行为来防止使用过多内存,除了崩溃

另一方面,datatase 的工作是分析表之间的关系,查询使用的实数(实际上是索引的基数和行上的静态以及索引的使用情况),并且引擎可以选择很多不同的机制,具体取决于数据的大小(合并连接、临时表等)。这意味着您可以拥有 256.278.242 个帖子和 145.268 个用户,平均拥有 5.684 个关注者,数据库的工作就是找到给您答案的最快方法。好吧,当您遇到非常大的数字时,您会发现所有数据库都不相同,但这是另一个问题。

在 PHP 方面,从第一个查询库中检索用户列表变得非常长(有大量关注的用户,比如说 15.000。简单地在内部构建带有 15000 个标识符的查询字符串将占用大量内存。Trasnferring这个对 SQL 服务器的新查询也会很慢。这绝对是错误的方式。

现在请注意构建 SQL 请求的方式。请求是您应该能够从头到尾阅读的内容,它解释了您真正想要的内容。这将有助于 SQL(良好)引擎选择正确的解决方案。

select `posts`.* 
from `posts`
  INNER JOIN `follow` ON posts`.`AuthorID`=`follow`.`poster`
where `follow`.`follower`='@userid' 
order by `posts`.`postid` desc
LIMIT 15

几点说明:

  • 我使用了 INNER JOIN。我想要一个 INNER JOIN,让我们来写吧,以后我会更容易阅读,查询分析器也应该是一样的。
  • 如果 @userid 是 int,则不要使用引号。请使用整数作为标识符(这确实比字符串快)。并且在 PHP 端转换 int"SELECT ..." . (int) $user_id ." ORDER ...或使用带参数的查询(这是为了安全)。
  • 我使用了 LIMIT 15,如果您想在帖子周围显示一些分页控制,也许也可以使用偏移量。假设此查询将从我的 5.642 个关注用户中检索 15.263 个文档,您不希望并且用户不希望在网页上显示这些 15.263 个文档。知道$limit这个数字是 15.263 是一件好事,但肯定不是请求限制。你知道这个数字,但如果数据库有一个好的查询分析器和一些好的内部统计数据,它也可能知道它。

请求限制有几个目标 1. 限制从数据库传输到 PHP 脚本的数据大小 2. 限制 PHP 脚本的内存使用量(一个包含 15.263 个文档的数组,其中包含一些 HTMl 内容……哎哟) 3. 限制最终用户输出的大小(并获得更快的响应)

于 2012-07-24T15:39:07.223 回答