0

私は MongoDB を初めて使用し、使用されているデータ モデリング パラダイムを先取りしようとしています。

少し背景を説明した方が良いと思います。私が顧客に物を売る会社だとしましょう。しかし、私の商品の価格は固定されていません。購入ごとに繰り返される物々交換のシーケンスがあります。(つまり、私の会社は価格を見積もり、彼らはカウンターオファー、私の会社のカウンターカウンターオファーなど). 私のデータベースの目的は、取引の進展を保存することです。私の会社には、さまざまなオプションで反対提案する能力があります。ユニーク顧客数は 1000 人未満です。そのため、次の設定があります。

{
   customer_id : Number
   unique_deal_id: Number
   parent_unique_deal_id: Number
   child_unique_deal_id's: [Number]
   deal : {
     // info on price of each good negotiated
   }
}

私のクエリの 100% が a) 特定の取引の取得、または b) 取引の「ブランチ」の取得に関係している場合、MongoDB では、顧客を正規化して独自のコレクションに分離しようとするか、すべてを単一のコレクション (およびインデックスの顧客)?

4

2 に答える 2

1

ここで文書構造が実際に問題になるとは思いません。これを別の視点から見てみましょう。これは会計帳簿のようなものだと考えてください。

line #, Date,  Description,   Count,  Price each
1, 02/25/2013,  Super widgets, 1000, $1   // <-- Strike though font
2, 02/25/2013, Super Widgets, 5000, $0.50 // <-- Strike though font
3, 02/26/2013, Super widgets 3500, $0.75

最後の行 #3 は、現在の集計です。日付を見ると、何が保存され、何が保存されていないかがわかります。「トランザクション」は、取引明細書と同じように展開されます。明細レコード項目の変更を取引に追加し、保持されていないものを「削除」します (削除せず、非アクティブとしてマークするだけです)。

私はあなたが3つのコレクションを持っていると思います:

  • 再販業者 - 会社
  • 取引(再販業者とお客様の間)
  • トランザクション アーカイブ (古いもの)

    { _id: mongoid, company_id: integer, ... その他のフィールド... transaction_log: [ { active: boolean, id: integer, date: datetime, description: text, count: integer, price: float?/integer? }, { アクティブ: ブール値、ID: 整数、日付: 日時、説明: テキスト、カウント: 整数、価格: 浮動小数点数?/整数? }, { アクティブ: ブール値、ID: 整数、日付: 日時、説明: テキスト、カウント: 整数、価格: 浮動小数点数?/整数? }, { アクティブ: ブール値、ID: 整数、日付: 日時、説明: テキスト、カウント: 整数、価格: 浮動小数点数?/整数? }, ... ] }

于 2013-07-22T01:15:43.187 に答える
1

これは、ライブで行うのがおそらく最善のデザイン ディスカッションだと思いますが、うまくいけば、正しい方向に導くことができます。

このシナリオには、顧客、取引、取引入札履歴という 3 つの主要なエンティティが関係しているようです。データを個別のコレクションに埋め込むか保存するかの決定は、開発者のアプリに固有の設計上の決定です。基本をまだ学んでいない場合は、無料のオンライン トレーニング コースを受講することを強くお勧めします。思考プロセスをガイドするのに役立つ、基本的なスキーマ設計に関するレッスンがあります。主なデータ アクセス パターンを検討しているときに、決定を下す方法をすでに直感的に知っているようです。

あなたのデータに対する私の理解に基づいて、私はおそらくあなたの顧客データを独自のコレクションに保存します. その理由は、あなたのアプリは取引とは無関係に顧客の詳細にアクセスする可能性が高く、アトミックな方法で顧客と取引にアクセスする必要がないように見えるからです (Mongodb はドキュメント レベルでアトミック操作を提供するように設計されています)。これらは、すべてのデータにわたって顧客データを複製することがおそらくより良い選択ではない理由のいくつかです。顧客がログインすると、顧客データが取得され、コンテキスト (つまり、顧客 ID) が得られます。その後、このコンテキストを使用して取引情報を読み取り、更新できます。あなたの取引コレクションは実際に見栄えがします。顧客 ID を使用して、取引や取引のさまざまなブランチを引き出すことができます (www.mongodb. それらを参照したい場合は org を参照してください。設計パターンが標準に非常によく一致していることに注意してください)。ただし、取引履歴を取引に埋め込むことには 1 つの危険性があります。現在、1 つのドキュメントに 16 MB の制限があることに注意してください。取引履歴のサブドキュメントをスリムに保つと、多くの履歴を保存できるはずです。ただし、アプリがマイクロ入札アプリのようなものである場合、16MB の制限が問題になる可能性があります。この場合、取引履歴レコードを別のコレクションの個々のドキュメントに保存する必要があります。理にかなっていれば、アプリでの読み取りが容易になる場合は (複数のターゲットを更新する必要がある可能性に対して)、最後の 10 件の入札などの冗長データを取引に保存することを選択できます。いずれにせよ、アプリをシンプルにし、データ アクセスを高速化するため、合理的であれば埋め込みを行ってください。

また、取引履歴を取引に埋め込むことになると、ドキュメントはドキュメントごとにサイズが大きくなります。MongoDB は、ドキュメントをディスク上に連続して保存し、迅速な更新と読み取りを実現します。つまり、ドキュメントが現在割り当てられているスペースを超えて大きくなると、MongoDB はドキュメント全体をディスク上の別の場所に移動します。これにより更新が遅くなる可能性があり、アプリケーションの更新が多い場合は問題になる可能性があります。タイミングの悪いドキュメントの移動を防ぐには、mongodb.org Web サイトでパディング ファクター オプションと「powersof2」設定の使用を調べてください。

于 2013-07-22T01:56:14.713 に答える