73

mongo db で複合主キーを処理する最善の方法を決定しようとしています。このシステムでデータを操作するための主なキーは、2 つの uuid で構成されています。uuid の組み合わせは一意であることが保証されていますが、個々の uuid はいずれも一意ではありません。

これを管理するには、いくつかの方法があります。

  1. 2 つの値で構成される主キーのオブジェクトを使用します (ここで提案されているように) 。

  2. 標準の自動生成された mongo オブジェクト ID を主キーとして使用し、キーを 2 つの個別のフィールドに保存してから、それら 2 つのフィールドに複合インデックスを作成します

  3. 主キーを 2 つの uuid のハッシュにする

  4. 私が現在気付いていない他の素晴らしい解決策

これらのアプローチのパフォーマンスへの影響は何ですか?

オプション 1 については、キーが連続していないため、挿入のパフォーマンスが心配です。これが従来の RDBMS システムを破壊する可能性があることはわかっており、MongoDB でも同様である可能性があることを示しています。

オプション 2 の場合、システムで使用されることのない主キーを使用するのは少し奇妙に思えます。また、クエリのパフォーマンスがオプション 1 ほど良くないようです。従来の RDBMS では、クラスター化されたインデックスが最良のクエリ結果を提供します。これは MongoDB にどの程度関連していますか?

オプション 3 の場合、これは 1 つの単一の id フィールドを作成しますが、挿入時に連続しません。このアプローチに他の長所/短所はありますか?

選択肢 4 についてですが、選択肢 4 とは何ですか?

また、将来的には MongoDB の代わりに CouchDB を使用する可能性についても議論されています。CouchDB を使用すると、別のソリューションが提案されますか?

詳細情報:この問題の背景については、こちらを参照してください。

4

4 に答える 4

54

オプション1を使用する必要があります。

主な理由は、パフォーマンスについて心配していると言うことです。常にそこにあり、すでに一意である _id インデックスを使用すると、2 番目の一意のインデックスを維持する必要がなくなります。

オプション 1 については、連続していないキーを持つことによる挿入パフォーマンスが心配です。私は、これが従来の RDBMS システムを破壊する可能性があることを知っており、これが MongoDB でも同様である可能性があることを示しています。

他のオプションはこの問題を回避しません。それらは _id インデックスからセカンダリ ユニーク インデックスにシフトするだけですが、今では 2 つのインデックスがあり、1 つはバランスが取れており、もう 1 つはランダム アクセスです。

オプション 1 に疑問を呈する理由は 1 つだけです。それは、1 つまたは別の UUID 値でドキュメントにアクセスする予定がある場合です。両方の値を常に提供している限り (この部分は非常に重要です)、すべてのクエリでそれらを常に同じ方法で並べ替える限り、_id インデックスは効率的にその目的を十分に果たします。

{ a:1, b:2 }サブドキュメントを比較するときに常に同じ方法で2つのUUID値を並べ替える必要がある理由の詳細として、{ b:2, a:1 }2つのドキュメントが_idの値を持つコレクションを持つことができます。そのため、最初にフィールド a で _id を格納する場合、すべてのドキュメントとクエリで常にその順序を維持する必要があります。

もう 1 つの注意点は、index on_id:1がクエリに使用できることです。

db.collection.find({_id:{a:1,b:2}}) 

ただし、クエリには使用できません

db.collection.find({"_id.a":1, "_id.b":2})
于 2014-04-26T22:43:53.087 に答える
10

オプション 4 があります。

自動_idフィールドを使用し、単一の複合インデックスではなく、両方の uuid に 2 つの単一フィールド インデックスを追加します。

  1. _idインデックスはシーケンシャル (これは では重要ではMongoDBありませんが) で、簡単に分割でき、MongoDB管理することができます。
  2. 2 つの uuid インデックスを使用すると、必要なあらゆる種類のクエリを作成でき (最初のクエリ、2 つ目のクエリ、または両方を任意の順序で使用)、1 つの複合インデックスよりも占有するスペースが少なくなります。
  3. 同じクエリで両方のインデックス (および他のインデックスも) を使用する場合、複合インデックスを使用しているかのようにそれらMongoDB交差します(v2.6 の新機能)。
于 2014-04-28T11:42:02.710 に答える
7

私は2つのオプションを選びますが、それには理由があります

  1. 最初に提案したように、両方の uuid から連結されたフィールドではなく、2 つの個別のフィールドを使用すると、将来のクエリ要求をサポートするために、または結果として、1 つのキーのカーディナリティが別のキーよりも高いことが判明した場合に、インデックスの他の組み合わせを作成する柔軟性が得られます。
  2. 連続していないキーを使用すると、シャード環境に挿入するときにホットスポットを回避するのに役立つ可能性があるため、それほど悪いオプションではありません。私の意見では、書き込みロックはデータベース レベル (2.6 より前) またはコレクション レベル (2.6 バージョン) にあるため、シャーディングはコレクションの挿入と更新をスケーリングするための最良の方法です。
于 2014-04-26T08:09:31.550 に答える
4

オプション 2 を使用していたでしょう。両方の UUID フィールドを処理するインデックスを引き続き作成できます。パフォーマンスは複合主キーと同じですが、操作がはるかに簡単になります。

また、私の経験では、一意の ID を指定したことを後悔したことはありません。厳密には必須ではありませんでした。多分それは不人気な意見ですが。

于 2014-04-22T18:15:26.567 に答える