2012-07-16 13 views
8

私は様々な状況で最大のクエリ効率を得るための理想的なドキュメント構造について疑問を抱きました。この特定のケースでMongoDBがどのようにメモリ内で動作するかを実際には分かっていないのは本当に私の負担です。あなたに仮説的なシナリオを教えてください。ユーザフォロワ/フォロワの最も効率的なクエリのための良いMongoDBドキュメント構造は何ですか?

フォロワーとフォロワのTwitterシステムを想像してみてください。確かにチラッと見た後、メインのオプションがあるように見える:各ユーザー文書で

  1. 、彼らは続く他のユーザーのすべての文書への参照を含む「信者」の配列。フォロワーは、他のユーザーの「user.followers」配列内の現在のユーザーを見つけることによって検出されます。主な欠点は、Followee検索の潜在的なクエリオーバーヘッドであるように見えます。また、特に "user.followers"の内容のクエリの場合、MongoDBはユーザーのドキュメントの必須フィールドにアクセスするだけですか、またはユーザーの全ドキュメントが見つかっただけで、そこから必要なフィールド値が検索され、キャッシュ/大規模なユーザーベースでのクエリで大幅に多くのメモリが必要になるような方法で格納されていますか?

  2. 各ユーザー文書には、「フォロワー」と「フォロワー」の両方を保存して、それぞれにすばやくアクセスできます。これは明らかに、それぞれのフィールドの両方のユーザー文書にユーザーBに続くユーザーAのエントリーが存在し、fromからの削除が他のユーザー文書と一致する削除を必要とするという意味で、重複データの欠点があります。技術的には、これは単純な削除のための潜在的な失敗のポイントの数を倍増させることを検討している可能性があります。また、MongoDBは、削除が発生したときにメモリに格納されたデータの "スイスチーズ"と言われていることから、2つのフィールドからの削除は、メモリホールの問題の効果を2倍にします。

  3. ユーザーのフォロワーを格納するための別のコレクションで、ユーザードキュメントに同様の方法で1つの質問がありますが、明らかにアクセスされるデータはフォロワーのみです。ユーザードキュメントには、各ユーザーは、そのデータへのアクセスを避けます。これは関係データベースの何かを感じているようですが、原則的にひどいアプローチではないことは分かっていますが、明らかにMongoのアーキテクチャーの下で(あるいは私が考慮していない)学ぶのが大好き!

誰もがこの上の任意の考えを持っているか、私はどこかに非常に関連し、かつ明白なドキュメントのページを逃してきた私に教えたい、あるいは(と思った私は愚かなことだということを教えたい場合なぜあなたの説明、);)私はあなたから聞くのが大好きです!

+0

どのようなプログラミング言語を使用しますか?それに応じて、基礎をなすドライバーがサポートしているかもしれないし、サポートしていないかもしれない特定の機能があります。私は特にDBRefsについて話しています。 http://docs.mongodb.org/manual/applications/database-references/ –

+0

これは良い点です。ありがとうございます。 PHPとNode.jsが混在していますが、現在は何も使用していない可能性があります。 – tdous

答えて

7

これは古典的なフォロワフォロイー問題であり、このリンクアウトit..Checkに誰も答えがあります:MongoDBのとSQL場合

mongo db design of following and feeds, where should I embed?

実際にこのような状況は、リレーショナルスキーマに非常によく適していませんあなただけの選択肢でした。しかし、これは、あなたが双方向の関係にある特殊なタイプの関係上の問題です。

http://forum.kohanaframework.org/discussion/10130/followers-and-following-database-design-like-twitter/p1

事がある、あなたがユーザー文書でフォロワーやフォロイーを保つことができるのいずれか、両方ではなく、二重欠失の問題を回避するため:これは、おそらくより良いグラフデータベースで処理することができます。あなたがMongoDBに固執しなければならない場合、(あなたが人をフォロー/アンフォローしないと仮定すると、です)、

私のプロフィールを見ると、私は...(?それは私が最初の場所でそれらを続いた理由だ、右)..私は従う人々に興味があると思います。そしてようなクエリん:これは、すべては以下の通りです誰

db.Users.find({ user_id : { $in : followees })

を教えてくれます私は(私のIDは 'user_id'と言っています)。

もう1つの理由は別の理由は、30〜40人のユーザーを格納するユーザー文書が何千ものユーザー文書を格納するユーザー文書に対して大丈夫であるように、フォロワー!フォローイン・ドキュメント・アプローチでは、全体的に均一なサイズのユーザー・ドキュメントが得られます。フォローイン・イン・ドキュメントのアプローチでは、非常に小さくても非常に大きなドキュメントもあります。また、follower_idとは別にフォロワーデータの量に応じて、かもしれないは、ドキュメントサイズの制限に注意したいと思っています。

+1

ニース!あなたは私が言っていたすべてのポイントをカバーしました!オプション2は間違いなくnoです。あなたが従っているユーザーのIDを格納することは、方法です。あなたのフォローしているユーザーのリストを取得することは、1つのクエリに過ぎず、インデックスを作成することができます。参照:http://www.mongodb.org/display/DOCS/Schema+Design –

+0

これも私が考慮する方法ですが、私はmongoの '無制限フィールド'のパフォーマンスの問題に少し気になります。これを貧しい選択にしてください。参照:http://stackoverflow.com/questions/9306815/mongodb-performance-with-growing-data-structureこれについてのあなたの考えは? – UpTheCreek

+0

@UpTheCreekここに無制限のフィールドは、私が従うpplのリストです。これが30〜40人のユーザーを超えて成長しないと仮定すると、何千人ものフォロワーを含む無制限のフィールドを持つことに比べて問題は少なくなります。ここでも、この引数はこのユースケースに特有のものです(Twitterスタイルのフォロワフォロイ)。 –

2

多かれ少なかれ多くの関係があることを考えれば、オプション(2)は私によく見えます。一致する削除については、2つのドキュメントの間に何らかの調整メカニズムがある限り、通常は問題になりません。

フラグメンテーションは一般にアプリケーションのアクセスパターンに依存し、一般にほとんどのデータシステムには問題があります。内部の断片化を避けるために、いくつかの重要な変更がmongoに加えられました。さらに、断片化を修正するためのオフライン圧縮の代替方法も存在します。

関連する問題