Ich verstehe die Unterschiede zwischen den beiden aus den Dokumenten.
uuid1()
:
Generieren Sie eine UUID aus einer Host-ID, einer Sequenznummer und der aktuellen Uhrzeit
uuid4()
:
Generiere eine zufällige UUID.
So uuid1
verwendet Maschine / Sequenz / Zeitinfo eine UUID zu erzeugen. Was sind die Vor- und Nachteile der Verwendung?
Ich weiß, uuid1()
dass Datenschutzbedenken bestehen können, da diese auf Maschineninformationen basieren. Ich frage mich, ob es bei der Auswahl des einen oder anderen etwas Feineres gibt. Ich benutze uuid4()
gerade, da es eine völlig zufällige UUID ist. Aber ich frage mich, ob ich uuid1
das Kollisionsrisiko verringern sollte .
Grundsätzlich suche ich nach Tipps für Best Practices zur Verwendung des einen gegen das andere. Vielen Dank!
Antworten:
uuid1()
Es wird garantiert, dass keine Kollisionen auftreten (unter der Annahme, dass Sie nicht zu viele gleichzeitig erstellen). Ich würde es nicht verwenden, wenn es wichtig ist, dass keine Verbindung zwischen demuuid
und dem Computer besteht, da die Mac-Adresse verwendet wird, um es für alle Computer eindeutig zu machen.Sie können Duplikate erstellen, indem Sie mehr als 2 14 uuid1 in weniger als 100 ns erstellen. Dies ist jedoch in den meisten Anwendungsfällen kein Problem.
uuid4()
generiert, wie Sie sagten, eine zufällige UUID. Die Wahrscheinlichkeit einer Kollision ist sehr, sehr, sehr gering. Klein genug, dass Sie sich darüber keine Sorgen machen sollten. Das Problem ist, dass ein schlechter Zufallszahlengenerator die Wahrscheinlichkeit von Kollisionen erhöht.Diese ausgezeichnete Antwort von Bob Aman fasst es gut zusammen. (Ich empfehle, die ganze Antwort zu lesen.)
quelle
uuid1
erzeugt nicht unbedingt eindeutige UUIDs, wenn Sie mehrere pro Sekunde auf demselben Knoten erzeugen. Beispiel :[uuid.uuid1() for i in range(2)]
. Es sei denn natürlich, es passiert etwas Seltsames, das ich vermisse.uuid1
hat eine Sequenznummer (4. Element in Ihrem Beispiel). Wenn Sie also nicht alle Bits im Zähler verbrauchen, haben Sie keine Kollision.Eine Instanz , wenn man bedenkt , kann
uuid1()
eher alsuuid4()
ist , wenn UUIDs auf separaten Maschinen hergestellt werden , zum Beispiel , wenn mehrere Online - Transaktionen Prozess auf mehreren Maschinen sind für die Zwecke Skalierung.In einer solchen Situation besteht das Risiko von Kollisionen aufgrund schlechter Auswahlmöglichkeiten bei der Initialisierung der Pseudozufallszahlengeneratoren, und auch die möglicherweise höhere Anzahl erzeugter UUIDs, erhöht die Wahrscheinlichkeit, dass doppelte IDs erstellt werden.
Ein weiteres Interesse
uuid1()
in diesem Fall besteht darin, dass die Maschine, auf der jede GUID ursprünglich erstellt wurde, implizit aufgezeichnet wird (im "Knoten" -Teil der UUID). Dies und die Zeitinformationen können hilfreich sein, wenn auch nur beim Debuggen.quelle
Mein Team hatte gerade Probleme mit der Verwendung von UUID1 für ein Datenbank-Upgrade-Skript, bei dem wir innerhalb weniger Minuten ~ 120.000 UUIDs generiert haben. Die UUID-Kollision führte zu einer Verletzung einer Primärschlüsseleinschränkung.
Wir haben Hunderte von Servern aktualisiert, aber auf unseren Amazon EC2-Instanzen ist dieses Problem einige Male aufgetreten. Ich vermute, dass eine schlechte Taktauflösung und die Umstellung auf UUID4 das Problem für uns gelöst haben.
quelle
Eine Sache, die Sie bei der Verwendung beachten
uuid1
sollten: Wenn Sie den Standardaufruf verwenden (ohneclock_seq
Parameter anzugeben), besteht die Möglichkeit, dass Sie auf Kollisionen stoßen: Sie haben nur 14 Bit Zufälligkeit (wenn Sie 18 Einträge innerhalb von 100 ns generieren, haben Sie eine Wahrscheinlichkeit von ungefähr 1% für eine Kollision Geburtstagsparadoxon / Angriff). Das Problem tritt in den meisten Anwendungsfällen nie auf, aber auf einer virtuellen Maschine mit schlechter Taktauflösung wird es Sie beißen.quelle
clock_seq
....Vielleicht ist etwas, das nicht erwähnt wurde, das der Lokalität.
Eine MAC-Adresse oder eine zeitbasierte Bestellung (UUID1) kann zu einer höheren Datenbankleistung führen, da es weniger Arbeit ist, Zahlen näher zusammen zu sortieren als zufällig verteilte Zahlen (UUID4) (siehe hier ).
Ein zweites verwandtes Problem ist, dass die Verwendung von UUID1 beim Debuggen hilfreich sein kann, selbst wenn Ursprungsdaten verloren gehen oder nicht explizit gespeichert werden (dies steht offensichtlich im Widerspruch zu dem vom OP erwähnten Datenschutzproblem).
quelle
Zusätzlich zur akzeptierten Antwort gibt es eine dritte Option, die in einigen Fällen nützlich sein kann:
v1 mit zufälligem MAC ("v1mc")
Sie können einen Hybrid zwischen v1 und v4 erstellen, indem Sie absichtlich v1-UUIDs mit einer zufälligen Broadcast-MAC-Adresse generieren (dies ist in der v1-Spezifikation zulässig). Die resultierende vU-UUID ist zeitabhängig (wie reguläres v1), es fehlen jedoch alle hostspezifischen Informationen (wie v4). Es ist auch in seiner Kollisionsbeständigkeit viel näher an v4: v1mc = 60 Bit Zeit + 61 zufällige Bits = 121 eindeutige Bits; v4 = 122 zufällige Bits.
Der erste Ort, an dem ich darauf stieß, war die Funktion uuid_generate_v1mc () von Postgres . Ich habe seitdem das folgende Python-Äquivalent verwendet:
(Hinweis: Ich habe eine längere + schnellere Version, die das UUID-Objekt direkt erstellt; kann posten, wenn jemand möchte)
Bei GROSSEN Anrufvolumina pro Sekunde kann dies die Zufälligkeit des Systems erschöpfen. Sie können
random
stattdessen das stdlib- Modul verwenden (es wird wahrscheinlich auch schneller sein). Aber seien Sie gewarnt: Es dauert nur einige hundert UUIDs, bis ein Angreifer den RNG-Status bestimmen und somit zukünftige UUIDs teilweise vorhersagen kann.quelle