2012-01-28 1 views
1

私はMongoDB + PHPをさまざまな種類のフィード(投稿、写真、投票など)とコメントとともに "facebookish"ニュースフィードに使用します。MongoDB performance:newsfeed architecture、subscribers、comments

各フィードは、いくつかの「チャネル」に属している - 現在、それはユーザ又はかもしれない(将来的には複数の容器があってもよいです)。

すべてのユーザーは、任意のチャンネルを購読することも、そのチャンネルから購読を禁止することもできます。

ここで、数多くのチャンネルと数多くのフィードがあるとします。チャンネル/フィード/コメントに最適な構造は何ですか?

私は2つのアプローチを考えている:

1)は、各フィードで購読者のリストを収集フィード:

db.feeds.find({date_added: "this week", channel_subscribers: "my_login"}); 
:私は最後のフィードを取得したい場合は

feeds: 
[ 
    {date_added: ..., 
    last_update: ..., 
    title: ..., 
    text: ..., 
    channel: ..., 
    channel_subscribers: [...], 
    comments_subscribers: [...], 
    comments: [...] 

    }, 
    {...}, 
    {...}, 
    {...} 
] 

新しいコメントでフィードを取得したい場合:

db.feeds.find({last_update: "this week", comments_subscribers: "my_login"}); 

長所:

  • シンプルかつ高速な測定値?

短所:

  • 私は/チャンネルから、私は トラフすべてのフィードやプッシュを実行する必要がため/ unsibscribeをサブスクライブしたい/ channel_subscribersのリストから自分の名前を引きます。 同じことが、チャネルコレクションに加入者のリストを保持:私は照会する必要があり

    channels: 
    [ 
        {channel_id:..., last_update: ..., subscribers: [...]}, 
        {channel_id:..., last_update: ..., subscribers: [...]} 
    ] 
    

    まず私がコレクションフィード

2)個別の「チャンネル」のトンを持っている場合、それが遅くなる可能性があり最終更新チャンネル:

subscribes = db.channels.find({last_update: "today", subscribers: "my_login"}) 

は今私のフィードを見つける:

db.feeds.find({channel: {$in: subscribes}], date_added: "today"}) 

長所:

  • 、シンプルで高速かつより安全なサブスクライブ/ unsubsribing。

短所:

  • 私はそれが遅いので、私はで$を避ける必要があり、私はこの演算子の内側に入れて サブスクライブをたくさん持っている場合は特に感じ(?)。このケースでは、我々はさらに大きな必要があります - :

3)

users: 
[ 
    {_id: ..., login: ..., email: ..., subscribes: [...]} 
] 

短所(ので、各ユーザーは自分のサブスクライブのアレイを有する)のユーザーコレクションにユーザーが加入してください以前の(#2)アプローチよりも$ inの内側に配置する配列。

4)あなたの提案ですか?

+0

MongoDBは、使用するデータ構造が最も一般的なユースケースに対応していることを推奨します。まだあなたの現在の構造を理解するのが少し難しいです。あなたはもう少しあなたの構造について詳しく説明できますか? – JohnP

+0

私の質問を簡略化してください。より速いもの:私のサブスクリプションのリストを保持し、その大きな配列を "$ in"演算子の中に置き、それによって私のフィードを取得します。 OR - ログイン名でフィードを取得する - すべてのフィードに大きな(〜2000)のサブスクライバが含まれている場合(そのような大きな配列にマルチキーインデックスを作成するのは良い習慣ですか?) – oyatek

+0

私は、フィード自体に加入者を残すことは悪い考えだと思います。リンクする方が良いかもしれません。これはちょっとしたSQLeyに見えますが、検索と削除も簡単に行えます。 – JohnP

答えて

1

OK私は自分で答えます。私はノートパソコンのWindows 7 32ビット/ 2GB RAMでテストを試みました。 は、私は、「フィード」コレクションを作成し、フィード500でそれを満たし:

feeds: 
[ 
{_id: ..., subscribers: [...]}, 
{_id: ..., subscribers: [...]}, 
] 

各「契約者」配列は、2000年の短いランダムな文字列名のリストを持っています。

まず、私のDBのサイズが60Mbから1.5Gbに増加したことに言及する必要があります。

シェルコマンドを実行すると、シェルコマンドdb.feeds.ensureIndex({subscribers: 1})が3分間ハングしてエラー:"can't map file memory - mongo requires 64 bit build for larger datasets"で停止しました。

だから、mongoのドキュメントの中にこのような大きなマルチキーフィールドを作成することは間違いありません。

+0

ちょっとメモしておきますが、32bitのmongoバージョンは[データ用に2GBのハード制限があります](http://blog.mongodb.org/post/137788967/32bit-limitations)。いずれにしても、参照がより速く簡単になるように、別々にすることは間違いありません。あなたは文字列ではなくユーザーオブジェクトにリンクしたいと思っているからです。 – JohnP