使用两个表JOIN显示关系,或者使用PHP函数


Show relationship using two table JOIN, or use PHP functions?

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

表格:

表:帖子
列: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内爆,然后执行中的where:

我想在这里告诉大家的一件事是,我将用户关注的用户数量存储在"用户"表的"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";


两种方法中哪一种更好?知道关注的总数量(当前用户关注的用户数量),能让第一种方法的速度比第二种方法更快吗
还有其他更好的方法吗?

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

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

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

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

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

另一方面,datatase的工作是分析表之间的关系、查询使用的实数(实际上是行上索引和静态的基数以及索引的使用),并且引擎可以根据数据的大小选择许多不同的机制(合并联接、临时表等)。这意味着你可能有256.278.242条帖子和145.268名用户,平均粉丝数为5.684,数据数据库的工作是找到最快的方法给你答案。好吧,当你达到非常大的数字时,你会发现所有的数据库都不相等,但这是另一个问题。

在PHP方面,从第一个查询coudl检索用户列表变得非常长(有大量的关注用户,比如说15000。简单地构建包含15000个标识符的查询字符串将占用相当大的内存。将这个新查询传递到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。我想要一个INNAR JOIN,让我们来写吧,它稍后对我来说更容易阅读,它应该对查询分析器也是一样的
  • 如果@userid是int,请不要使用引号。请使用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.限制最终用户输出的大小(并获得更快的响应)