|
based on v22 (2010-10-03更新) - オリジナル 導入Mongoでは、リレーショナルデータベースのデザインでするような"正規化"はそれほど必要ありません。サーバサイドでの"join"がないからです。一般的には、1つの最上位のオブジェクトレベルに対して、1つのデータベースコレクションを作ることになるでしょう。 すべての"class"について、コレクションを作ることはあまりしません。代わりにembedオブジェクトを使います。例えば、下記の図では、studentsとcoursesの2つのコレクションがあります。studentドキュメントは、courseコレクションを参照する"address"ドキュメントをembedします。
scoreを他のテーブルに入れ、外部キーとしてstudentテーブルにリレーションを持つことになるであろうリレーショナルなスキーマと対比してみてください。 Embed (組み込み) vs. Reference (参照)Mongoで、スキーマデザインをするときに考えるポイントは、"オブジェクトを自分のコレクションとして持つことにメリットがあるか? または、 他のコレクションのオブジェクトにembedするべきか?" です。 リレーショナルデータベースでは、サブアイテムは通常、(パフェーマンスのために正規化をしない、という場合を除き)別のテーブルにします。Mongoでは、これは推奨されません。オブジェクトをembedする方が効率がいいからです。 データはディスクの同じ場所に保存され、クライアントーサーバの通信回数も減ります。つまり、”なぜ、embedオブジェクトにしたくないのか?” ということを自問することになります。 なぜ、Referenceは遅いんでしょうか? 上記のstudentの例を考えてみましょう。 studentオブジェクトで、以下を実行します。 print( student.address.city ); この操作は、addressはembedオブジェクトなので常に速いです。また、studentがRAMにある場合、addressもRAMに入っています。しかし、 print( student.scores[0].for_course.name ); もしこれが、最初の scores[0] へのアクセスだった場合、シェルまたは、ドライバーは以下のQueryを実行することになります。 // pseudocode for driver or framework, not user code
student.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});
つまり、それぞれのreferenceがデータベースのクエリになります。通常、 questionのコレクションでは、 _id にはインデックスが設定されています。そのためクエリーは速いです。しかし、たとえ、すべてのデータがRAMに入っていたとしても、アプリケーションサーバからデータベースのクライアント、サーバ間のコミュニケーションには遅延があります。一般的に、RAMのキャッシュにヒットする場合、1msぐらいの応答時間が期待されます。しかし、1,000 studentsをイテレートする場合では、1 studentで1回referenceを参照するだけで、たとえキャッシュされていたとしても、全体で1秒以上かかることになります。しかし、もし1つのアイテムだけのルックアップでよければ、この時間は1msのオーダーになり、webのページロードで受け入れられるような時間になります。(注意: dbキャッシュにすでに入っている場合、1,000 studentのロードは、データベースから結果がバッチで戻るので、もしかすると1秒よりかなり速いかもしれません。) どのようなときにembedにするか、またはreferenceにするか、といくつかの一般的なルールです。
ユースケースいくつかのユースケースを検討してみましょう。
インデックスの設定スキーマデザインをするときの次の検討事項はインデックスについてです。一般的なルールとしては、 リレーショナルデータベースでインデックスを設定したいようなところに、Mongoでもインデックスを作成します。
MongoDBプロファイリング機能は、インデックスを張るべきところの情報を提供します。 インデックスの追加はコレクションに対する書き込みを遅くすることに注意してください。書き込みに対して読み込みが多いコレクションにはたくさんインデックスを使ってください(ストレージをたくさん使うことを気にしない場合)。読み込みより書き込みが多いコレクションでは、インデックスはとても負荷が高いです。 コレクションの数Mongoのコレクションは多様な種類のデータを持てるので、一つのコレクションにすべての オブジェクト を入れることもできます。 このアプローチはいくつかのオブジェクトデータベースで取られています。しかしパフォーマンス的な理由から、このアプローチは推奨しません。Mongoでは、一つのコレクションの中のデータは、ディスクの中で連続して置かれる傾向があります。そのため、コレクションの全体のscanもできますし、効率的です。複数のコレクションは、バッチ処理で高いスループットを出すためにとても重要です。 参照 |


IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.
These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group. blog comments powered by Disqus