私は、mongo dbで複合主キーを処理する最良の方法を決定しようとしています。このシステムのデータを操作するための主なキーは、2つのuuidで構成されています。 uuidの組み合わせは一意であることが保証されていますが、個々のuuidはいずれも一意ではありません。
これを管理する方法がいくつかあります。
2つの値で構成される主キーのオブジェクトを使用します(提案されているように here )
標準の自動生成mongoオブジェクトIDを主キーとして使用し、キーを2つの別々のフィールドに保存してから、これら2つのフィールドに複合インデックスを作成します
主キーを2つのuuidのハッシュにする
私が現在気づいていない他のいくつかの素晴らしいソリューション
これらのアプローチのパフォーマンスへの影響は何ですか?
オプション1では、非順次キーがあるために挿入のパフォーマンスが心配です。これにより、従来のRDBMSシステムが停止する可能性があることを知っています。また、MongoDBでもこれが当てはまるという兆候を見てきました。
オプション2の場合、システムで使用されることのない主キーを持つことは少し奇妙に思えます。また、クエリパフォーマンスはオプション1ほど優れていないようです。従来のRDBMSでは、クラスター化インデックスが最適なクエリ結果を提供します。 MongoDBでこれはどの程度関連していますか?
オプション3の場合、これは1つの単一のidフィールドを作成しますが、再び挿入するときは連続しません。このアプローチに他の長所/短所はありますか?
オプション4の場合...オプション4とは何ですか?
また、将来のある時点でMongoDBの代わりにCouchDBを使用する可能性についての議論もあります。 CouchDBを使用すると、別のソリューションが提案されますか?
詳細:問題に関する背景を見つけることができます ここ
オプション1を選択してください。
主な理由は、パフォーマンスが心配だということです。常に存在し、既に一意である_idインデックスを使用すると、2番目の一意のインデックスを維持する必要がなくなります。
オプション1の場合、非シーケンシャルキーを使用した場合の挿入パフォーマンスが心配です。これにより、従来のRDBMSシステムが停止する可能性があることを知っています。また、MongoDBでもこれが当てはまるという兆候を見てきました。
他のオプションはこの問題を回避せず、単に_idインデックスからセカンダリユニークインデックスにシフトしますが、2つのインデックスが作成されます。
オプション1を疑問視する理由は1つだけです。これは、1つまたは他のUUID値のみでドキュメントにアクセスする場合です。常に両方の値を提供し、(この部分は非常に重要です)すべてのクエリで常に同じ方法で順序付けている限り、_idインデックスはその完全な目的を効率的に果たします。
サブドキュメント{ a:1, b:2 }
が{ b:2, a:1 }
と等しくない場合、2つのUUID値を常に同じ方法で順序付けする必要があることの詳細については、2つのドキュメントにそれらの値が含まれているコレクションを作成できます。 _id。したがって、フィールド_idを最初に格納する場合、すべてのドキュメントとクエリで常にその順序を維持する必要があります。
もう1つの注意点は、_id:1
のインデックスがクエリに使用できることです。
db.collection.find({_id:{a:1,b:2}})
しかし、それはnotクエリに使用可能です
db.collection.find({"_id.a":1, "_id.b":2})
私にはあなたのためのオプション4があります:
自動_id
フィールドを使用し、単一の複合インデックスではなく、両方のuuidに2つの単一フィールドインデックスを追加します。
_id
インデックスはシーケンシャルになり(MongoDB
ではそれほど重要ではありませんが)、簡単にシャーディングでき、MongoDB
に管理させることができます。MongoDB
は複合インデックスを使用しているかのように 交差 (v2.6の新機能)になります。私は2つのオプションに行きますが、理由があります
オプション2を選択します。両方のUUIDフィールドを処理するインデックスを作成することができ、パフォーマンスは複合プライマリキーと同じである必要がありますが、操作がはるかに簡単になります。
また、私の経験では、厳密に必須ではない場合でも、何か一意のIDを与えたことを後悔したことはありません。おそらくそれは不人気な意見でしょう。