Auftreffwahrscheinlichkeit von ObjectId vs UUID in einem großen verteilten system
Wenn man bedenkt, dass eine UUID rfc 4122 (16 bytes), die ist viel größer als eine MongoDB ObjectId (12 bytes), ich bin versucht, herauszufinden, wie Ihre Kollisions-Wahrscheinlichkeit zu vergleichen.
Ich weiß, dass ist etwas, um Recht unwahrscheinlich, aber in meinem Fall die meisten ids generiert werden, die innerhalb einer großen Anzahl von mobilen clients, die nicht in einem beschränkten Satz an Servern. Ich Frage mich, ob in diesem Fall, es ist ein berechtigtes Anliegen.
Im Vergleich zu den normalen Fall, wo alle ids generiert werden, indem eine kleine Anzahl von clients:
- Es könnte Monate dauern, um eine Kollision erkennen, da die Erstellung von Dokumenten
- - IDs generiert werden, die von einem sehr viel größeren Kundenstamm
- Jeder Kunde hat eine niedrigere ID-generation rate
- Warum sind Sie die mobilen clients zum erstellen der ObjectIds, oder einer permanenten Id, wenn Sie sich sorgen um die Integrität der Daten?
- Die clients offline, und speichern von Informationen, die möglicherweise nicht synchronisiert werden für eine lange Zeit. Ich will nicht zu zwingen, eine 100 - % - online-mobile app
- die meisten client - Bibliothek-Implementierungen erstellen der
_id
Wert standardmäßig. Nicht sagen, dass es eine "gute Idee", eine direkte Verbindung herzustellen. Aber "ObjectId" generation ist durchaus gültig. - Persönlich würde ich nicht bauen, oder entwerfen Sie ein system, das erlaubt Kunden, dies zu tun. Ich würde zuweisen von temporären Ids wenn man offline ist. Ich würde überlegen, nicht anders als erwartet ein client nicht direkt schreiben, MongoDb, ohne Umweg über einen Daten-Validierung Schicht.
- wissen die meisten Kunden, die standardmäßig. Ein offline-client könnte noch erstellen, aber Sie müssen überprüft werden, vor dem einfügen in die collection.
- Ich möchte vermeiden, nicht mit ObjectId da MongoDB optimiert diese Daten geben. Manchmal ist es sogar erforderlich, Sie die Vergangenheit (Aggregation framework?)
- Ich mag den Inhalt von @mnemosyn, wenn für nicht viel anderes, als es macht den monotonic zeigen Sie, dass ist inhärent in der Gestaltung der spec. Als solche fand ich auch diese eine faire Frage, und eine sehr gültige Gegenleistung für andere in der Zukunft sehen. Die Gesamt-Punkt sagt "die Kollision Faktor" ist wie ein viel mehr als "ziemlich unwahrscheinlich".
- All dies machte mich zu überdenken, die Rolle der UUIDs für offline-clients. @WiredPrairie Kommentar auf die zeitliche ids warten auf Validierung Ebene besser zu sein scheint für die Zukunft gerüstet ist, als nur unter Berufung auf UUIDs, aber auch so ein Schmerz zu implementieren... naja, partition Toleranz war noch nie ein Stück Kuchen. Vielen Dank für das "Geburtstags-problem" zu erwähnen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das klingt wie eine sehr schlechte Architektur zu mir. Sind Sie mit einer zwei-tier-Architektur? Warum sollten die mobilen clients haben direkten Zugriff auf die db? Wollen Sie wirklich verlassen sich auf Netzwerk-basierte Sicherheit?
Trotzdem, einige überlegungen über die Kollisions-Wahrscheinlichkeit:
Weder UUID noch ObjectId verlassen sich auf Ihre schiere Größe, D. H. beide sind keine Zufallszahlen, sondern Sie Folgen einem Schema, das versucht, systematisch zu reduzieren Kollision Wahrscheinlichkeit. Im Falle von ObjectIds, Ihre Struktur ist:
Dies bedeutet, dass, im Gegensatz zu UUIDs, ObjectIds sind monotonic (außer innerhalb einer Sekunde), das ist wahrscheinlich Ihre wichtigste Eigenschaft. Monotone Indizes Ursache der B-Baum gefüllt werden effizienter, es erlaubt die paging-id und ermöglicht eine "Standard-Art" von id, um Ihren Cursor stabil, und natürlich, Sie tragen einen easy-to-timestamp extrahieren. Das sind die Optimierungen, die Sie sollten sich bewusst sein, und Sie können riesig sein.
Wie Sie sehen können, von der Struktur der anderen 3 Komponenten, Kollisionen werden sehr wahrscheinlich, wenn Sie tun, > 1k-Einsätze/s auf einem einzigen Prozess (eigentlich nicht möglich, auch nicht von einem server), oder wenn die Anzahl der Maschinen wächst Vergangenheit über 10 (siehe Geburtstags-problem), oder wenn die Anzahl der Prozesse auf einem einzelnen Computer wächst zu groß (dann wieder, das sind keine zufälligen zahlen, aber Sie sind wirklich einzigartig auf einer Maschine, aber Sie müssen gekürzt werden, um zwei bytes).
Natürlich, für eine Kollision auftreten, Sie müssen übereinstimmen in alle diese Aspekte, so dass selbst wenn zwei Maschinen die gleiche hash-Maschine, es wäre immer noch erfordern eine client einfügen mit der gleiche-Zähler-Wert exakt in der gleichen Sekunde und die gleiche Prozess-id, aber ja, diese Werte kollidieren könnten.
Schauen wir uns die Definition für "ObjectId" aus der Dokumentation:
So lassen Sie uns dies in der Kontext ein "mobile client".
Also die Punkte:
Wert für die "Sekunden seit der Epoche". Das ist ziemlich random pro Anfrage. Eine So geringe Kollision Auswirkungen nur auf diese Komponente. Wenn auch in "Sekunden".
"Machine identifier". Also das ist eine verschiedenen client die Generierung der
_id
Wert. Dies ist das entfernen der Möglichkeit, Sie weiter "Kollision".Die "Prozess-id". Also, wo ist zugänglich Samen ( und das sollten Sie), dann wird der erzeugte
_id
hat mehr chance zur Vermeidung von Kollisionen.Den "Zufallswert". Also ein weiterer "client", der es irgendwie geschafft zu generieren, die alle die gleichen Werte wie oben und noch geschafft zu generieren, die gleichen zufälligen Wert.
Bottom line ist, wenn , dass ist nicht überzeugend genug argument, um zu verdauen, dann geben Sie einfach Ihren eigenen "uuid" - Einträge als den "primary key" - Werte.
Aber IMHO, sollte das ein fair überzeugendes argument zu berücksichtigen, dass die Kollision Aspekte sind hier sehr breit. Um das Mindeste zu sagen.
Den voll Thema ist wahrscheinlich nur ein wenig "zu breit". Aber ich hoffe, das bewegt Betrachtung ein bisschen mehr Weg von "Sehr unwahrscheinlich" und auf etwas mehr Beton.