1. ホーム
  2. mongodb

[解決済み] MongoDBのリレーションシップ:埋め込みか参照か?

2022-03-17 21:34:25

質問

私はリレーショナルデータベースからMongoDBに乗り換えたばかりです。コメント付きの質問構造を設計したいのですが、コメントにどのリレーションシップを使えばいいのかわかりません。 embed または reference ?

のような、いくつかのコメントを含む質問。 スタックオーバーフロー のような構造になっています。

Question
    title = 'aaa'
    content = bbb'
    comments = ???

とりあえず、埋め込みコメントを使いたい(たしか embed がMongoDBでは推奨されている)、こんな感じです。

Question
    title = 'aaa'
    content = 'bbb'
    comments = [ { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'} ]

クリアだけど、このケースは心配だなぁ。 指定したコメントを編集したい場合、その内容や質問をどのように取得すればよいのでしょうか? はありません。 _id を見つけることができ、また question_ref をクリックすると、その質問を見つけることができます。(私はとても初心者なので、これをする方法が _idquestion_ref .)

を使用しなければならないのでしょうか? ref ではなく embed ? では、コメント用に新しいコレクションを作らなければならないのでしょうか?

どのように解決するのですか?

これは科学というより芸術です。その スキーマに関する Mongo ドキュメント は良い参考文献ですが、ここでは考慮すべき点をいくつか紹介します。

  • なるべくたくさん入れる

    Documentデータベースの利点は、たくさんのJoinを省けることです。 最初の直感は、1つのドキュメントにできる限り多くのものを配置することでしょう。 MongoDB のドキュメントには構造があり、その構造の中で効率的にクエリを実行できます (つまり、必要な部分だけを取り出すことができるので、ドキュメントのサイズはあまり気にする必要がありません)。 特に、親ドキュメントから離れては役に立たないデータは、同じドキュメントの一部であるべきです。

  • 複数箇所から参照できるデータは、独自のコレクションに分離する。

    これは、ストレージスペースの問題というより、データの一貫性の問題です。 多くのレコードが同じデータを参照する場合、1つのレコードを更新し、他の場所でそのレコードへの参照を維持する方が効率的であり、エラーの可能性も低くなります。

  • 文書サイズに関する考慮点

    MongoDBは1つのドキュメントに4MB(1.8では16MB)のサイズ制限を課しています。 GBのデータの世界では小さく聞こえますが、これは3万件のツイートや250件のStack Overflowの回答、20枚のフリッカー写真にも相当します。 一方、これは一般的なWebページで一度に提示したい情報よりもはるかに多い。 まず、何がクエリーを容易にするかを考えてみましょう。 多くの場合、文書サイズを気にするのは、最適化としては早計です。

  • 複雑なデータ構造。

    MongoDBは任意の深いネストしたデータ構造を保存できますが、それらを効率的に検索することはできません。 データがツリーやフォレスト、グラフのような場合は、各ノードとそのエッジを別々のドキュメントに格納する必要があります。 (この種のデータ用に特別に設計されたデータストアがあるので、そちらも検討してみてください。)

    また 指摘されている ドキュメント内の要素のサブセットを返すことは不可能であることよりも。 もし、各文書からいくつかのビットを選び出す必要があるのなら、それらを分離する方が簡単でしょう。

  • データの整合性

    MongoDBは、効率と一貫性の間でトレードオフの関係にあります。 ルールとしては、ひとつのドキュメントに対する変更は 常に アトミック 一方、複数のドキュメントに対する更新はアトミックであると仮定してはいけません。 また、サーバー上でレコードをロックする方法もありません(クライアントのロジックにquot;lock"フィールドなどを使って組み込むことは可能です)。 スキーマを設計する際には、どのようにデータの一貫性を保つかを検討してください。 一般的に、ドキュメントに保存するデータは多ければ多いほどよいでしょう。

あなたのおっしゃるとおり、コメントを埋め込み、各コメントにObjectIDのidフィールドを与えます。 ObjectIDにはタイムスタンプが埋め込まれているので、必要に応じてcreated atの代わりにそれを使うことができます。