2012-06-24 6 views
6

私は、文字列の所有者(文字列ごとに1人以上の所有者)とともにデータベースに文字列を格納しています。MongoDBのデータを関連付けるには?

私は常に、従来のリレーショナル・データベースであるMySQLのに働いてきました。その場合、1つのテーブルに一意のIDと共に文字列を格納し、次に2番目のテーブルの所有者(複数のレコードとして)とともに一意のIDを格納します。

私はその後、参加SQLを使用してオーナーによって、文字列を取得することができます。

私は今のMongoDBを使用してプロジェクトに取り組んでいます、と私は上記と同じことをやっています。 NoSQLデータベースで作業する場合

これは間違った方法と考えられるでしょうか? NoSQLを使って作業するとき、私は「関係」の観点から考えるべきではありませんか?私はMongoDBの中で同じことを達成することを考えることができ

もう一つの方法は、このようにそれを記憶している。

{ 
    "string": "foobar", 
    "owners": [ 
     "owner1", 
     "owner2", 
     "owner3" 
    ] 
} 

ただし、この場合には、私は「それぞれowner1が所有するすべての文字列」を検索する方法をわかりませんよ。

+7

"NoSQL"は傘として使用しないでください。あなたはMongoDBを使っています。それでおしまい。"NoSQL"とは* too muchとtoo little * :-)を意味します。 –

答えて

2

これは正しいアプローチのようです。ただし、それは常にプロジェクトの全体、目標(パフォーマンス、柔軟性)、最も頻繁に実行するクエリ、随時クエリを実行する必要がある場合、およびその他の要因によって決まります。一般的には、ネストしたドキュメントを使用して、書いたように、結合と外部キーを使用する正しい方法です。

maximum document size(現在は16MB)も念頭に置いてください。指定された文字列の所有者が数多く(数十万人の場合など)気になる場合があります。 dbasemanの答え補完するために

+0

ありがとうございます。私はそれに近づくことができないので、最大の文書サイズについて心配する必要はありません。私の最も一般的なクエリは挿入されます。非常に、非常にいくつかの発見。 – xbonez

5

をはい、あなたのアプローチは大丈夫そうです。あなたは簡単に

db.collection.find({owners: 'author1'}) 

のMongoDBは、特別な方法で配列を扱うので、これは可能である「それぞれowner1が所有するすべての文字列」を検索することができます。 NoSQLデータベースで作業する場合

+0

クエリの例を示していただきありがとうございます。 – xbonez

6

これは間違った方法と考えられるでしょうか? NoSQLを使って作業するとき、私は「関係」の観点から考えるべきではありませんか?

埋め込みの場合は非常に多くの質問がありますが、それほど多くはありません。あなたが埋め込むしたい場合は考慮する必要があり、ここで言及されていない

代:

  • 文書のサイズは、大規模増加されますか?そうであれば、文書は頻繁にディスク上を移動することがありますが、これは悪いことです。
  • は、関連する行は、多くは、私が働いているコレクション(すなわちvideouserを埋め込むことはできません)に参加しています。この場合、特に冗長データの更新時に、関連する行からサブ文書に冗長データをコピーするときに問題が発生する可能性があります。
  • これらの結果を表示するにはどうすればよいですか?

結果を表示することは、埋め込むかどうかの重要な決定要因です。高い数の行にページングする必要がある場合は、通常のクエリまたは集約フレームワークで$slice演算子を使用する必要があります。 1000時には、かなり高速かもしれませんが、遅かれ早かれメモリ内の動作が通常のクエリよりも遅くなることが認められています(実際は常にそうであるはずです)。

あなたは複雑なソートを必要とし、サブ文書の表示場合は、これらを分割し、代わりの文書構造持ってしたいことがあります。私は、これは実際にいるので、あなたのデータのために、とにかく、よりパフォーマンスの高い構造体であってもよいと思います

{ 
    "string": "foobar", 
    "owners": [ 
     ObjectId(), 
     ObjectId(), 
     ObjectId() 
    ] 
} 

ownerはコレクションのuser行のように聞こえます。

サブ文書にユーザーの変更可能なデータを入力する代わりに、_idを参照することができます。関係を埋め込むことができるので、これはかなりクールですが、同時にドキュメントはほとんど成長しません。ディスクの動きが少なくて済み、小さな作業セットが全体的なパフォーマンスを向上します。それだけでなく、オーナーの_idもほとんど変更されないので、このデータのサブセットで最もよく投げる必要がある操作は、作成と削除です。

複雑な並べ替えと改ページに戻る。このデータを使用すると、往復ですべてownerのIDを取得し、別の往復でを使用して、通常のクエリでusersテーブル内のその行の所有者の行を照会することができます。

この構造全体的に、私が見つけたのは、非常に高性能です。

もちろん、この構造はクエリに依存しますが、代わりに文字列idをユーザーに格納する方が良いかもしれませんが、この場合はユーザーがおそらく多くの文字列を所有できるため、文字列側に多くの>関係が埋め込まれています。

うまくいけば、これは助け、私は円でラウンドを行っていない、埋め込まれたデータを扱う場合

3

私はモンゴで不可分の動作に精通しになってお勧めします。 良い出発点は、ここでは次のようになります。 http://docs.mongodb.org/manual/core/data-modeling/#atomicity

をあなたの特定のケースでは、あなたがa findAndModify()操作を使用したいとしているあなたの「所有者」列に(Sammayeによって推奨されているように)ユーザーのObjectIdを追加/削除する場合そのドキュメントへの多くの書き込みが発生したときにもデータの整合性が維持されることを保証するためにdocという文字列を使用します。所有者を削除する場合は、重複

  • を防ぐために、所有者、$ addToSetを追加する場合は、

    1. $

    両方を引っ張っ:

    この操作の中で、私は次の演算子を使用してお勧めします http://docs.mongodb.org/manual/reference/operators/#update-operators-array

  • 関連する問題