0

私はmyspaceに似たソーシャルネットワークを持っていますが、PHPとmysqlを使用しています。自分自身からのみ投稿されたユーザーと、友達であることが確認されたユーザーからの掲示板を表示するための最良の方法を探しています。

これには3つのテーブルが含まれます

friend_friend=このテーブルには誰が友達であるかのレコードが格納されますfriend_bulletins=これには掲示板が格納されますfriend_reg_user=これは名前や写真のURLなどのすべてのユーザーデータを含むメインユーザーテーブルです

以下に掲示板とフレンドテーブルスキームを投稿します。ユーザーテーブルにとって重要なフィールドのみを投稿します。

-テーブルのテーブル構造friend_bulletin

CREATE TABLE IF NOT EXISTS `friend_bulletin` (
  `auto_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(10) NOT NULL DEFAULT '0',
  `bulletin` text NOT NULL,
  `subject` varchar(255) NOT NULL DEFAULT '',
  `color` varchar(6) NOT NULL DEFAULT '000000',
  `submit_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `status` enum('Active','In Active') NOT NULL DEFAULT 'Active',
  `spam` enum('0','1') NOT NULL DEFAULT '1',
  PRIMARY KEY (`auto_id`),
  KEY `user_id` (`user_id`),
  KEY `submit_date` (`submit_date`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=245144 ;

-テーブルのテーブル構造friend_friend

CREATE TABLE IF NOT EXISTS `friend_friend` (
  `autoid` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(10) DEFAULT NULL,
  `friendid` int(10) DEFAULT NULL,
  `status` enum('1','0','3') NOT NULL DEFAULT '0',
  `submit_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `alert_message` enum('yes','no') NOT NULL DEFAULT 'yes',
  PRIMARY KEY (`autoid`),
  KEY `userid` (`userid`),
  KEY `friendid` (`friendid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2657259 ;

使用されるfriend_reg_userテーブルフィールドauto_id=これはユーザーID番号ですdisp_name=これはユーザー名ですpic_url=これはサムネイル画像パスです

  • Bulletinsには、フレンドリストにあるユーザーIDによって投稿されたすべてのBulletinが表示されます。
  • 自分で投稿したすべての掲示板も表示する必要があります
  • うまくスケーリングする必要があります、友達のテーブルは数百万行です

//1古いメソッドは副選択を使用します

SELECT auto_id, user_id, bulletin, subject, color, fb.submit_date, spam
FROM friend_bulletin AS fb
WHERE (user_id IN (SELECT userid FROM friend_friend WHERE friendid = $MY_ID AND status =1) OR user_id = $MY_ID)
ORDER BY auto_id

//友達が少ないアカウントで使用した別の古いメソッド。これは、この形式ですべての友達の文字列を返す別のクエリを使用するためです$ str_friend_ids = "1,2,3,4,5,6 、7,8 "

select auto_id,subject,submit_date,user_id,color,spam
from friend_bulletin
where user_id=$MY_ID or user_id in ($str_friend_ids) 
order by auto_id DESC

私のサイトは非常に大きくなっているので、これらはパフォーマンスに良くないことを知っているので、JOINSを試しています

自分で投稿するように変更する必要があることを除いて、これで必要なものがすべて得られると思います。これをWHERE部分に追加すると、投稿された投稿ごとに複数の結果が返されるように見えます。私がフリードであるという結果を返し、それから私は自分自身を友達だと考えようとしますが、それはうまくいきません。

この投稿全体の私の主なポイントは、このタスクを実行するための最良のパフォーマンス方法についての意見を受け入れることですが、多くの大きなソーシャルネットワークには、友達だけが投稿したアイテムのリストを返す同様の機能があります。他のより速い方法がなければなりませんか???? JOINSはパフォーマンスに優れていないことを読み続けていますが、他にどのようにこれを行うことができますか?私はインデックスを使用し、専用のデータベースサーバーを持っていますが、ユーザーベースが大きいことを覚えておいてください。それを回避する方法はありません。

SELECT fb.auto_id, fb.user_id, fb.bulletin, fb.subject, fb.color, fb.submit_date, fru.disp_name, fru.pic_url
FROM friend_bulletin AS fb
LEFT JOIN friend_friend AS ff ON fb.user_id = ff.userid
LEFT JOIN friend_reg_user AS fru ON fb.user_id = fru.auto_id
WHERE (
ff.friendid =1
AND ff.status =1
)
LIMIT 0 , 30
4

1 に答える 1

1

まず、データベースをパーティション分割して、必要なプライマリ行を持つテーブルにのみアクセスできるようにすることができます。使用頻度の低い行を別のテーブルに移動します。

JOINはパフォーマンスに影響を与える可能性がありますが、私が見たところ、サブクエリはこれ以上優れていません。一度にすべてのデータを取得しないように、クエリをリファクタリングしてみてください。また、そのクエリの一部はアプリの他の場所で1回実行でき、それらの結果は変数に保存されるか、キャッシュされるようです。

たとえば、ユーザーごとに接続されている友達の配列をキャッシュし、クエリの実行時にそれを参照し、新しい友達が追加/削除されたときにのみキャッシュを更新できます。

また、システムの構造とコードアーキテクチャにも依存します。ボトルネックが完全にデータベースに含まれているとは限りません。

于 2009-07-23T04:57:59.457 に答える