0

私はマイクロブログのウェブサイトを作っています。ユーザーはお互いをフォローできます。Twitterのように、現在のユーザーがフォローしているユーザーに基づいて、現在のユーザー($ userid)の投稿のストリーム(アクティビティストリーム)を作成する必要があります。私はこれを実装する2つの方法を知っています。どちらがいいですか?

テーブル:

表:投稿
列:PostID、AuthorID、TimeStamp、Content

表:フォロー
列:ポスター、フォロワー

最初の方法は、これら2つのテーブルを結合することです。

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


2番目の方法は、$ useridがフォローしているユーザーの配列(ポスター)を作成し、この配列でphp implodeを実行してから、次の場所で実行する

ことです。ユーザーが`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;
}


これで、現在の$useridがフォローしているユーザーIDのコンマ区切りリストができました。

そして、アクティビティストリームを作成するために投稿を選択します。

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


2つの方法のどちらが優れていますか?そして、フォローの総数(現在のユーザーがフォローしているユーザーの数)を知ることで、2番目の方法と同じように最初の方法で物事を速くすることができますか?
他のより良い方法はありますか?

4

2 に答える 2

3

あなたは最初のオプションでずっと行くべきです。PHPコードではなく、mysqlサーバーでデータを処理するために常に可能な限り努力してください。PHPは、MySQLが実行している間、操作の結果を暗黙的にキャッシュしません。

最も重要なことは、データに正しくインデックスを付けることです。「EXPLAIN」ステートメントを使用してデータベースを可能な限り最適化したことを確認し、#1を使用してデータをリンクしてみてください。

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

これにより、後で統計を計算することもできますが、2番目の方法では統計の一部を処理する必要があります。

于 2012-07-24T15:11:21.137 に答える
1

最初の重要な点は、PHPはページの構築には優れていますが、データの管理には非常に悪いことです。PHPによって操作されるものはすべてメモリをいっぱいにし、クラッシュを除いて、多くのメモリの使用を防ぐためにPHPで特別な動作を適用することはできません。

一方、datataseの仕事は、テーブル間の関係、クエリで使用される実数(実際には、行のインデックスと静的のカーディナリティ、およびインデックスの使用法)を分析することであり、エンジンによってさまざまなメカニズムを選択できます。データのサイズ(マージ結合、一時テーブルなど)。つまり、256.278.242の投稿と145.268のユーザーがいる可能性があり、平均フォロワー数が5.684の場合、データベースの仕事は、答えを出すための最速の方法を見つけることです。さて、あなたが本当に大きな数にぶつかると、すべてのデータベースが等しくないことがわかりますが、それは別の問題です。

PHP側では、最初のクエリcoudlからユーザーのリストを取得するのが非常に長くなりました(フォローしているユーザーの数が多い場合、たとえば15.000。内部に15,000個の識別子を含むクエリ文字列を作成するだけでかなりのメモリが必要になります。転送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

いくつかの意見:

  • INNERJOINを使用しました。INNERJOINが必要です。書きましょう。後で読みやすくなり、クエリアナライザーでも同じになるはずです。
  • @useridがintの場合、引用符は使用しないでください。識別子にはintを使用してください(これは文字列よりも実際に高速です)。また、PHP側では、intをキャストする"SELECT ..." . (int) $user_id ." ORDER ...か、パラメーターを指定してクエリを使用します(これはセキュリティのためです)。
  • 私はLIMIT15を使用しましたが、投稿の周囲にページネーション制御を表示したい場合は、オフセットも使用できます。このクエリが私の5.642のフォローしているユーザーから15.263のドキュメントを取得するとします。あなたは、これらの15.263のドキュメントをWebページに表示することを望んでいません。そして、$limitその数が15.263であることを知っていることは良いことですが、要求の制限については確かにそうではありません。あなたはこの数を知っていますが、それが優れたクエリアナライザといくつかの優れた内部統計を持っていれば、データベースもそれを知っているかもしれません。

リクエストの制限にはいくつかの目標があります。1。データベースからPHPスクリプトに転送されるデータのサイズを制限します。2。PHPスクリプトのメモリ使用量を制限します(HTMlのものを含む15.263ドキュメントの配列...痛い)3。制限最終的なユーザー出力のサイズ(そしてより速い応答を得る)

于 2012-07-24T15:39:07.223 に答える