wake-up-neo.com

MongoDB und zusammengesetzte Primärschlüssel

Ich versuche, den besten Weg zu finden, um mit einem zusammengesetzten Primärschlüssel in einer Mongo-Datenbank umzugehen. Der Hauptschlüssel für die Interaktion mit den Daten in diesem System besteht aus 2 Benutzeroberflächen. Die Kombination der UUIDs ist garantiert eindeutig, aber keine der einzelnen UUIDs ist eindeutig.

Ich sehe ein paar Möglichkeiten, dies zu verwalten:

  1. Verwenden Sie ein Objekt für den Primärschlüssel, das aus 2 Werten besteht (wie vorgeschlagen hier )

  2. Verwenden Sie eine standardmäßige automatisch generierte Mongo-Objekt-ID als Primärschlüssel, speichern Sie meinen Schlüssel in zwei separaten Feldern und erstellen Sie dann einen zusammengesetzten Index für diese beiden Felder

  3. Machen Sie den Primärschlüssel zu einem Hash der beiden UUIDs

  4. Eine andere großartige Lösung, die mir derzeit nicht bekannt ist

Welche Auswirkungen haben diese Ansätze auf die Leistung?

Bei Option 1 mache ich mir Sorgen um die Einfügeleistung, da es keine sequenziellen Schlüssel gibt. Ich weiß, dass dies traditionelle RDBMS-Systeme töten kann, und ich habe Hinweise darauf gesehen, dass dies auch in MongoDB der Fall sein könnte.

Für Option 2 erscheint es etwas seltsam, einen Primärschlüssel zu haben, der niemals vom System verwendet wird. Außerdem scheint die Abfrageleistung möglicherweise nicht so gut zu sein wie in Option 1. In einem herkömmlichen RDBMS liefert ein Clustered-Index die besten Abfrageergebnisse. Wie relevant ist das in MongoDB?

Für Option 3 würde dies ein einzelnes ID-Feld erstellen, aber es wäre beim Einfügen nicht sequentiell. Gibt es andere Vor- und Nachteile für diesen Ansatz?

Für Option 4: Was ist Option 4?

Es wird auch diskutiert, in Zukunft möglicherweise CouchDB anstelle von MongoDB zu verwenden. Würde die Verwendung von CouchDB eine andere Lösung vorschlagen?

MEHR INFO: Hintergrundinformationen zum Problem finden Sie hier

45
herbrandson

Sie sollten mit Option 1 gehen.

Der Hauptgrund ist, dass Sie sagen, dass Sie sich Sorgen um die Leistung machen. Wenn Sie den immer vorhandenen und bereits eindeutigen _id-Index verwenden, können Sie sparen, dass Sie einen zweiten eindeutigen Index führen müssen.

Bei Option 1 mache ich mir Sorgen über die Leistung beim Einfügen, wenn nicht sequentielle Schlüssel vorhanden sind. Ich weiß, dass dies traditionelle RDBMS-Systeme töten kann, und ich habe Hinweise darauf gesehen, dass dies auch in MongoDB der Fall sein könnte.

Ihre anderen Optionen umgehen dieses Problem nicht. Sie verschieben es einfach vom _id-Index in den sekundären eindeutigen Index. Jetzt haben Sie zwei Indizes, einen mit ausgewogenem Verhältnis und einen mit wahlfreiem Zugriff.

Es gibt nur einen Grund, Option 1 in Frage zu stellen. Dies ist der Fall, wenn Sie vorhaben, über den einen oder anderen UUID-Wert auf die Dokumente zuzugreifen. Solange Sie beide Werte immer angeben und (dieser Teil ist sehr wichtig), ordnen Sie sie in all Ihren Abfragen immer auf dieselbe Weise an, dann wird der Index _id seinen vollen Zweck effizient erfüllen.

Um zu erläutern, warum Sie sicherstellen müssen, dass Sie die beiden UUID-Werte beim Vergleich von Filialdokumenten immer auf die gleiche Weise sortieren. { a:1, b:2 } ist ungleich zu { b:2, a:1 } - Sie könnten eine Sammlung haben, in der zwei Dokumente diese Werte für _id hatten. Wenn Sie also zuerst _id mit Feld a speichern, müssen Sie diese Reihenfolge in allen Ihren Dokumenten und Abfragen beibehalten.

Die andere Vorsicht ist, dass der Index auf _id:1 kann abgefragt werden:

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

aber es wird nicht für die Abfrage verwendbar sein

db.collection.find({"_id.a":1, "_id.b":2})
39
Asya Kamsky

Ich habe eine Option 4 für Sie:

Verwenden Sie die automatische _id field und addiere 2 einzelne Feldindizes für beide uuids anstelle eines einzelnen zusammengesetzten Index.

  1. Das _id index wäre sequentiell (obwohl das in MongoDB weniger wichtig ist), leicht zu zerbrechen, und Sie können MongoDB es verwalten lassen.
  2. Mit den 2 uuid-Indizes können Sie jede Art von Abfrage durchführen (mit dem ersten, mit dem zweiten oder mit beiden in beliebiger Reihenfolge). Sie belegen weniger Platz als 1 zusammengesetzter Index.
  3. Wenn Sie beide Indizes (und auch andere) in derselben Abfrage verwenden, wird MongoDBsie überschneiden (neu in v2.6), als ob Sie einen zusammengesetzten Index verwenden würden.
6
i3arnon

Ich würde für die 2 Option gehen und es gibt warum

  1. Wenn Sie zwei separate Felder anstelle eines aus beiden UUIDs verknüpften Felds haben, wie im ersten Abschnitt vorgeschlagen, können Sie andere Indexkombinationen erstellen, um zukünftige Abfrageanforderungen zu unterstützen, oder wenn sich herausstellt, dass die Kardinalität eines Schlüssels höher als die eines anderen Schlüssels ist.
  2. wenn Sie keine sequenziellen Schlüssel haben, können Sie die Hotspots beim Einfügen in eine Sharded-Umgebung vermeiden. Daher ist dies keine so schlechte Option. Sharding ist meiner Meinung nach die beste Möglichkeit, Einfügungen und Aktualisierungen für die Auflistungen zu skalieren, da die Schreibsperre auf Datenbankebene (vor 2.6) oder Auflistungsebene (Version 2.6) liegt.
4
Boris

Ich hätte Option 2 gewählt. Sie können weiterhin einen Index erstellen, der beide UUID-Felder verarbeitet, und die Leistung sollte der eines zusammengesetzten Primärschlüssels entsprechen, es sei denn, die Arbeit mit diesem ist wesentlich einfacher.

Außerdem habe ich es meiner Erfahrung nach nie bereut, eine eindeutige ID angegeben zu haben, auch wenn dies nicht unbedingt erforderlich war. Vielleicht ist das aber eine unpopuläre Meinung.

2
Brent