33

データを 2 つのドキュメントに分割することが適切な方法でデータを構築する状況に、多く遭遇したようです。チェーン店で、各顧客が訪れた店舗を保存していたとしましょう。店舗と顧客は、他の多くのものと相互作用するため、独立したデータである必要がありますが、それらを関連付ける必要があります。

したがって、簡単な答えは、ユーザーの ID をストア ドキュメントに格納するか、ストアの ID をユーザーのドキュメントに格納することです。ただし、ID は役に立たないため、表示目的で他の 1 ~ 2 個のデータにアクセスしたい場合がよくあります。お客さんの名前とか店名とか。

  1. 通常、ドキュメント全体の複製を保存しますか? それとも、必要なデータを保存するだけですか? おそらく、ドキュメントのサイズと必要なドキュメントの量によって異なります。
  2. 重複データがあるという事実をどのように処理しますか? データが変更されたときにデータを探しに行きますか? ロード時に一定の間隔でデータを更新しますか? 古いデータを許容できる場合にのみ複製しますか?

あらゆる種類の「ベスト プラクティス」への意見および/またはリンク、または少なくともこれらのトピックに関する十分な理由のある議論を歓迎します。

4

3 に答える 3

32

基本的に、 freshstaleの 2 つのシナリオがあります。

最新データ

重複データの保存は簡単です。重複データの維持は難しい部分です。したがって、最も簡単な方法は、最初から重複データを保存しないことで、メンテナンスを回避することです。これは主に、新しいデータが必要な場合に役立ちます。参照のみを保存し、情報を取得する必要があるときにコレクションをクエリします。

このシナリオでは、余分なクエリが原因でオーバーヘッドが発生します。別の方法は、重複データのすべての場所を追跡し、更新ごとにすべてのインスタンスを更新することです。これには、特にあなたが言及したようなN対Mの関係では、オーバーヘッドも伴います。いずれにせよ、新しいデータが必要な場合は、オーバーヘッドが発生します両方の長所を活かすことはできません。

古いデータ

古いデータを保持する余裕があれば、作業はずっと簡単になります。クエリのオーバーヘッドを回避するために、重複データを格納できます。重複データを維持する必要がないように、重複データを保存しません。少なくとも積極的ではありません。

このシナリオでは、ドキュメント間の参照のみを保存することもできます。次に、定期的な map-reduce ジョブを使用して複製データを生成します。その後、個別のコレクションではなく、単一の map-reduce の結果をクエリできます。これにより、クエリのオーバーヘッドを回避できますが、データの変更を追跡する必要もありません。

概要

他のドキュメントへの参照のみを保存します。古いデータに余裕がある場合は、定期的な map-reduce ジョブを使用して重複データを生成します。重複データを保持しないようにします。複雑でエラーが発生しやすいです。

于 2010-10-18T08:43:53.977 に答える
16

ここでの答えは、データがどれだけ最新である必要があるかによって異なります。

@Nielsはここに良い要約を持っていますが、「チート」できることに注意するのは公平だと思います.

ユーザーが使用するストアを表示するとします。ここでの明らかな問題は、Store 自体が重要すぎるため、User 内に Store を「埋め込む」ことができないことです。しかし、できることは、いくつかのストア データをユーザーに埋め込むことです。

「店名」など、表示したいものを入力してください。したがって、ユーザー オブジェクトは次のようになります。

{
  _id : MongoID(),
  name : "Testy Tester",
  stores : [ 
             { _id : MongoID(), "name" : 'Safeway' },
             { _id : MongoID(), "name" : 'Walmart' },
             { _id : MongoID(), "name" : 'Best Buy' }
            ]
}

このようにして、典型的な「グリッド」ビューを表示できますが、店舗に関する詳細データを取得するにはリンクが必要です。

于 2010-10-18T16:52:57.683 に答える
2

直接の質問に答えるには:

  1. 重複はありません。
  2. 重複はありません。

;)

必要な唯一の重複は、重みのような「単純な」値 (たまたま同じである可能性がありますが、個別に保存する時間または空間のいずれかで効率的ではありません) と、別のオブジェクトを参照する ID (重複値) です。 、しかし、それらが置き換える複製オブジェクトデータよりもはるかに小さく、管理しやすい)。

さて、あなたのシナリオに答えるために、あなたが望むのは多対多の関係です。ここでの通常の解決策は、おそらく StoreUsers と呼ばれる 3 番目の「スルー」または「ブリッジ」テーブル/コレクションを作成することです。

StoreUsers
----------
storeuser_id
store_id
user_id

別のストア、別のユーザー、または 1 つのストア内の多数のユーザーのいずれであっても、ストアとユーザー間のリンクごとにレコードをこれに追加します。次に、ストアまたはユーザーのいずれかについて、これを個別に検索できます。MongoDB もこのアプローチを推奨しています。RDBMS 固有ではありません。

于 2011-10-09T07:49:23.533 に答える