2

Cities{name: "NYC", area: "1223", people: [1,2,3]} と Person {personId:1, name:"abc"} の 2 つの個別のコレクションがあるとします。

ご覧のとおり、都市の個人 ID (RDBMS の外部キーのようなもの) をリンクしています。

Id = 1 の人物を削除することにした場合、RDBMS のカスケード削除操作で発生するように、Cities の people 配列を更新したいと思います MOngoDB にはトランザクションがありません。何らかの理由で都市に対して「カスケード削除」のような操作を実行できなかった場合、データベースが矛盾した状態になる可能性があります。MongoDBのアトミック操作として「人の削除+都市のカスケード削除」全体を確認するにはどうすればよいですか? それができない場合は、リンクよりも常に埋め込みを優先しますか?

4

3 に答える 3

3

操作の速度と一貫性の両方の点で、リンクよりも埋め込みの方が適しています。あなたが達成しようとしているのは、mongodb でのトランザクション操作です。これは、複数のドキュメントが関係するため、アトミックではありません。

各都市が各個人を参照するのではなく、各個人ドキュメントから都市を参照することは非常に簡単です。これは、この多対 1 の関係にとってより健全な構造です。

同様のケースでアプリケーションにとってデータの一貫性が重要な場合は、RDBMS トランザクションをエミュレートする mongodb の 2 フェーズ コミット パターンの使用を検討することをお勧めします。

于 2013-02-06T14:10:24.573 に答える
1

MongoDBのアトミック操作として「人の削除+都市のカスケード削除」全体を確認するにはどうすればよいですか?

他の人が言ったように、MongoDB には 2 フェーズ コミットのクライアント側バージョンがありますが、これは次のとおりです。

  • 2 フェーズのトランザクション コミットを提供しない
  • アトミックではない
  • かなりのオーバーヘッドがある
  • クライアント側です(実際には、これがサーバー側であることから得られる利益を拒否します。つまり、失敗します)
  • 障害が発生した場合、情報とトランザクションの安全性を提供できません

そうは言っても、アプリケーションがデータベースに書き込み、失敗しないことを信頼できる場合は、2 フェーズ コミットの MongoDB エディションがここで機能する可能性があります。ただし、偽の 2 フェーズ コミットを使用する余分なオーバーヘッドを追加する代わりに、クエリを次々に実行しないのはなぜですか。

通常、削除クエリの1つが成功した場合、mongodbに書き込むことができると想定されていますが、カスケードの親行を削除済みまたは何かとしてほとんど「マーク」せず、後で戻ってくる専用のcronjobがあり、一貫した方法ですべてをクリーンアップします(そこでそれを行うと、クライアントが遅延するため)。

どのスキーマ設計が最適かについては、埋め込みが優先されるとは限りません。私はあなたが次のように言っていることに気づきました:

次に、都市の人の配列を更新したい

$pullそのアレイで使用するには、おそらくaまたは同様のものを必要とするでしょう。その配列がかなり大きくなると、メモリ内操作は$pull2 つの個別のコレクションをクエリするよりも多少遅くなることに注意してください。

結局のところ、十分な知識がないため、スキーマ設計について実際にアドバイスすることはできません。そのため、そのままにしておきます。

編集

他の答えはどちらも重要ですが。個人文書にを埋め込むと、city_id実際にリレーションを 1 回の呼び出しでカスケードできます。もちろん、これは奇妙です。通常、子レコードが多すぎて Mongo ドキュメントに収まらない場合がありますが、このシナリオは当てはまります。

于 2013-02-06T14:34:53.290 に答える
0

スキーマの設計は、データ アクセス パターンと一致する必要があります。したがって、Cities コレクションの personID ではなく、'city:NYC' のキーと値のペアを people コレクションに含めたほうがよいでしょう。NYC のすべての人の ID を持っていると、課された 16 MB のドキュメント サイズ制限を超える可能性があるからです。 Mongodb ドキュメントでは、配列が何百万もの要素で構成されるためです。

これにより、常に変化している都市の人数を更新するよりも、個人の都市を更新する方が簡単になります (頻度が低いため)。おそらく、複数の更新を管理する最も安全な方法は、アプリケーション コードを使用することです。

于 2013-02-06T14:03:52.940 に答える