Frage

Ich sehe nicht wirklich den Punkt der UUID . Ich weiß, dass die Wahrscheinlichkeit einer Kollision effektiv null , sondern effektiv null ist nicht einmal in der Nähe unmöglich.

Kann jemand ein Beispiel geben, wo man keine andere Wahl als UUID zu benutzen? Von allen Anwendungen die ich gesehen habe, kann ich einen alternativen Entwurf ohne UUID sehen. Sicher das Design könnte etwas komplizierter sein, aber zumindest ist es nicht eine von Null verschiedenen Ausfallwahrscheinlichkeit hat.

UUID riecht wie globale Variablen zu mir. Es gibt viele Möglichkeiten, globale Variablen für einfacheres Design zu machen, aber es ist nur faul Design.

War es hilfreich?

Lösung

Ich schrieb den UUID-Generator / Parser für Ruby, so halte ich mich zum Thema einigermaßen gut informiert zu sein. Es gibt vier große UUID Versionen:

Version 4 UUID sind im Wesentlichen nur 16 Byte der Zufallsdaten aus einem kryptografisch sicheren Zufallszahlengenerator gezogen, mit einigem Bit-twiddling der UUID-Version und Variante zu identifizieren. Diese sind extrem unwahrscheinlich kollidieren, aber es könnte passieren, wenn ein PRNG verwendet wird, oder wenn Sie nur zufällig wirklich, wirklich, wirklich, wirklich, wirklich Pech.

Version 5 und Version 3 UUIDs verwenden, um die SHA1 und MD5-Hash-Funktionen jeweils einen Namespace mit einem Stück bereits eindeutiger Daten zu kombinieren, um eine UUID zu erzeugen. Dies wird zum Beispiel können Sie eine UUID von einer URL erzeugen. Collisions hier sind nur möglich, wenn die zugrunde liegende Hash-Funktion auch eine Kollision hat.

Version 1 UUIDs sind die häufigsten. Sie nutzen die MAC-Adresse der Netzwerkkarte (die, wenn nicht gefälscht, sollte eindeutig sein) sowie einen Zeitstempel, zuzüglich der üblichen Bit-Fummeln die UUID zu erzeugen. In dem Fall einer Maschine, die nicht eine MAC-Adresse hat, die 6 Bytes Knoten sind mit einem kryptographisch sicheren Zufallszahlengenerator erzeugt. Wenn zwei UUIDs in Sequenz erzeugt schnell genug, dass der Zeitstempel des vorherigen UUID übereinstimmt, wird der Zeitstempel wird um 1 inkrementiert Collisions sollte nicht auftreten, es sei denn, eine der folgenden Ereignisse eintritt: Die MAC-Adresse gespooft wird; Eine Maschine zwei unterschiedliche UUID erzeugende Anwendungen ausgeführt werden erzeugt UUIDs auf die exakt gleiche Zeit; Zwei Maschinen ohne Netzwerkkarte oder ohne Benutzerebene Zugriff auf die MAC-Adresse sind, die gleiche Zufallssequenz Knoten gegeben, und erzeugen UUID an dem exakt gleichen Zeitpunkt; Wir laufen aus Bytes, die die Zeitstempel und Roll zurück auf Null zu stellen.

Realistisch betrachtet, keines dieser Ereignisse auftritt zufällig innerhalb einer ID Raumes der einzigen Anwendung. Es sei denn, Sie akzeptieren IDs auf, sagen sie, eine Internet-weite Skala, oder mit einer nicht vertrauenswürdigen Umgebung, wo böswillige Personen etwas vielleicht in der Lage schlecht im Fall einer ID-Kollision zu tun, es ist einfach nicht etwas, was Sie kümmern sollen. Es ist wichtig zu verstehen, dass, wenn Sie passieren die gleiche Version 4 UUID zu erzeugen, wie ich in den meisten Fällen, es spielt keine Rolle. Ich habe die ID in einer ganz anderen ID Raum von Ihnen erzeugt. Meine Anwendung wird nie über die Kollision wissen, so dass die Kollision keine Rolle spielt. Ehrlich gesagt, in einer einzigen Anwendung Raum ohne böswillige Akteure, die Vernichtung allen Lebens auf der Erde lange auftreten, bevor Sie eine Kollision haben, auch an einer Version 4 UUID, auch wenn Sie schon einige UUIDs pro Sekunde sind zu erzeugen.

Auch 2 ^ 64 * 16 256 Exabyte. Wie in, müßten Sie im Wert von IDs 256 Exabyte speichern, bevor Sie eine Chance von 50% einer ID-Kollision in einem einzigen Anwendung Raum hatten.

Andere Tipps

Die Sache, die UUID Sie kauft, dass es sehr schwierig ist, anders zu tun, ist eine eindeutige Kennung zu erhalten , ohne mit einer zentralen Behörde zu konsultieren oder zu koordinieren. Das allgemeine Problem in der Lage, ohne irgendeine Art von Managed-Infrastruktur, so etwas zu bekommen, ist das Problem der UUID lösen.

Ich habe gelesen, dass die Chance auf eine UUID Kollision auftretenden zum Geburtstagsparadox nach 50% einmal 2 ^ 64 UUIDs erzeugt wurden. Jetzt 2 ^ 64 ist eine ziemlich große Zahl, aber eine 50% ige Chance einer Kollision scheint viel zu riskant (zum Beispiel, wie viele UUIDs müssen vorhanden sein, bevor eine 5% ige Chance einer Kollision gibt es - auch das scheint wie ein zu große Wahrscheinlichkeit) .

Das Problem mit dieser Analyse ist ein doppelter:

  1. UUIDs sind nicht ganz zufällig - es Hauptkomponenten des UUID sind, die Zeit und / oder ortsbasierte. Also eine echte Chance haben, bei einer Kollision, müssen die kollidierenden UUIDs Tobe an der exakt gleichen Zeit von verschiedenen UUID-Generatoren erzeugt. Ich würde sagen, dass es zwar eine vernünftige Chance, dass mehrere UUID könnte zugleich erzeugt werden, gibt es genug andere klebrige Masse (einschließlich Informationen über den Standort oder zufälligen Bits), um die likeyhood einer Kollision zwischen diesen sehr kleinen Satz von UUIDs zu machen fast unmöglich .

  2. streng genommen UUIDs nur unter dem Satz von anderen UUID eindeutig sein müssen, dass sie möglicherweise gegen verglichen werden. Wenn Sie eine UUID sind zu erzeugen als Datenbankschlüssel zu verwenden, ist es egal, wenn irgendwo anders in einem bösen alternativen Universum, dass die gleiche UUID verwendet wird, um eine COM-Schnittstelle zu identifizieren. Genau wie es wird keine Verwirrung verursachen, wenn es jemand (oder etwas) anders genannt „Michael Burr“ auf Alpha-Centauri ist.

Alles hat eine Nicht-Null-Chance des Scheiterns. Ich würde konzentriert sich auf vielen wahrscheinlichen Probleme auftreten (das heißt fast alles, was man sich vorstellen kann) als die Kollision von UUIDs

Ein Schwerpunkt auf „vernünftig“ oder, wie Sie es nennen, „effektiv“: gut genug ist, wie die reale Welt funktioniert. Die Menge an Rechenarbeit beteiligt bei der Deckung, diese Lücke zwischen „praktisch einzigartig“ und „wirklich einzigartig“, ist enorm. Einmaligkeit ist eine Kurve mit abnehmendem Ertrag. An einem gewissen Punkt auf dieser Kurve gibt es eine Linie zwischen dem „eindeutig genug“ ist immer noch erschwinglich, und wir dann Kurve sehr steil. Die Kosten von mehr Einzigartigkeit Zugabe wird recht groß. Unendliche Einzigartigkeit hat unendlich Kosten.

UUID / GUID ist, relativ gesehen, eine rechnerisch schnelle und einfache Möglichkeit, um eine ID zu erzeugen, die sein kann vernünftig angenommen universell eindeutig sein. Dies ist sehr wichtig in vielen Systemen, die Daten von zuvor unverbundenen Systeme integrieren müssen. Zum Beispiel: Wenn Sie ein Content Management System haben, die auf zwei verschiedenen Plattformen läuft, aber an einem gewissen Punkt, um den Inhalt von einem System in das andere zu importieren. Sie haben keine IDs ändern wollen, so dass Ihre Referenzen zwischen Daten aus dem System A intakt bleiben, aber Sie wollen keine Kollisionen mit in System erstellten Daten B. Ein UUID diese löst.

Es ist nie absolut notwendig, eine UUID zu erstellen. Es ist jedoch zweckmäßig, einen Standard zu haben, wo offline Benutzer können jeweils einen Schlüssel zu etwas mit einer sehr geringen Wahrscheinlichkeit einer Kollision erzeugen.

Dies kann in der Datenbankreplikation Auflösung unterstützen etc ...

Es wäre leicht für Online Benutzer ohne den Aufwand oder die Möglichkeit einer Kollision eindeutigen Schlüssel für etwas zu erzeugen, aber das ist nicht das, was UUIDs sind.

Wie auch immer, ein Wort über die Wahrscheinlichkeit einer Kollision, entnommen aus Wikipedia:

  

Um diese Zahlen zu relativieren, ein jährliches Risiko, Hit   von einem Meteoriten in 17 Milliarden, das entspricht einer Wahrscheinlichkeit sein wird geschätzt   zu den Chancen von ein paar Dutzend Billionen von UUIDs in einem Jahr zu schaffen und   mit einem Duplikat. Mit anderen Worten, nach nur Erzeugung 1000000000   UUIDs jede Sekunde für die nächsten 100 Jahre, ist die Wahrscheinlichkeit der Schaffung   nur ein Duplikat würde etwa 50% sein.

Es gibt auch eine Nicht-Null-Wahrscheinlichkeit, dass jedes Teilchen im Körper gleichzeitig Tunnel durch den Stuhl sitzen auf Sie und Sie werden sich plötzlich auf dem Boden finden sitzen.

Machen Sie sich Sorgen darüber?

Ein klassisches Beispiel ist, wenn Sie zwischen zwei Datenbanken replizieren.

DB (A) fügt einen Datensatz mit int ID 10 und zugleich DB (B) erzeugt einen einen Datensatz mit in ID 10. Dies ist eine Kollision.

Mit UUID wird dies nicht passieren, da sie nicht übereinstimmen. (Fast sicher)

Ich habe ein System für den UUIDs zu vermeiden. Stellen Sie einen Server irgendwo auf und hat es so, dass jedes Mal ein paar Stück Software, eine universell eindeutige Kennung will sie diesen Server kontaktieren und es reicht eine aus. Einfach!

Abgesehen davon, dass es einige wirklich praktische Probleme damit, auch wenn wir geradezu Bosheit ignorieren. Insbesondere kann dieser Server ausfallen oder aus einem Teil des Internet nicht mehr erreichbar ist. Der Umgang mit Serverausfall erfordert Replikation, und das ist sehr schwer Recht zu erhalten (siehe die Literatur auf dem Paxos-Algorithmus dafür, warum die Konsensbildung ist umständlich) und ist auch ziemlich langsam. Außerdem, wenn alle Server von einem bestimmten Teil der Netto nicht erreichbar sind, kein der Kunden zu diesem Subnetz angeschlossen wird in der Lage sein, etwas zu tun, weil sie alle für neues IDs würden warten.

So ... einen einfachen Wahrscheinlichkeits Algorithmus verwenden, um sie zu erzeugen, dass es unwahrscheinlich ist, während die Laufzeit der Erde, oder (Fonds und) baut eine wichtige Infrastruktur zum Scheitern verurteilt, die ein Einsatz PITA und häufige Ausfälle sein wird. Ich weiß, welche ich für gehen würde.

Wenn man sich nur auf die Alternativen z.B. für eine einfache Datenbank-Anwendung, die Datenbank jedes Mal abfragen müssen, bevor Sie ein neues Objekt erstellen, werden Sie feststellen, dass bald UUID mit effektiv der Komplexität des Systems reduzieren. Zugegeben - wenn Sie int Schlüssel verwenden, das sind 32-Bit, die in einem Viertel der 128-Bit-UUID gespeichert werden. Zugegeben - UUID Generation Algorithmen benötigen mehr Rechenleistung als nur eine Zahl erhöht wird. Aber wen interessiert es? Der Aufwand für die Verwaltung eine „Autorität“ zuweisen sonst eindeutige Zahlen leicht überwiegt die um Größenordnungen, abhängig von Ihrer beabsichtigten Einzigartigkeit ID Raum.

Auf UUID == faul Design

Ich bin nicht einverstanden sein über Ihre Kämpfe Kommissionierung. Wenn ein doppelter UUID statistisch unmöglich ist, und die Mathematik bewiesen ist, dann sorgen warum? Zeit zu verbringen, um den kleinen N UUID Erzeugungssystem entwerfen, ist unpraktisch, gibt es immer ein Dutzend andere Möglichkeiten können Sie Ihr System verbessern.

Ich habe nicht die ganze Gerede über die Wahrscheinlichkeit einer Kollision. Ich kümmere mich nicht um Kollision. Ich kümmere obwohl über die Leistung.

https://dba.stackexchange.com/a/119129/33649

  

UUIDs ist eine Leistung Katastrophe für sehr große Tabellen. (200K Zeilen   nicht "sehr groß".)

     

Ihre # 3 ist wirklich schlecht, wenn die Charcter SET ist UTF-8 - CHAR (36)   belegt 108 Bytes!

     

UUIDs (GUIDs) sind sehr "random". Mit ihnen entweder als UNIQUE oder einem   Primärschlüssel für große Tabellen ist sehr ineffizient. Das ist wegen   um den Tisch / Index einen neuen UUID INSERT Sie jedes Mal springen mit   oder SELECT von UUID. Wenn die Tabelle / Index zu groß in Cache zu passen   (Siehe innodb_buffer_pool_size, die kleiner als RAM sein muss,   typischerweise 70%), die ‚next‘ UUID nicht zwischengespeichert werden kann, also eine langsame Platte   schlagen. Wenn der Tisch / Index ist 20 mal so groß wie der Cache-Speicher, nur 1 / 20th   (5%) der Treffer zwischengespeichert werden - Sie sind I / O-bound

.      

Also, nicht verwenden UUIDs es sei denn, entweder

     

Sie haben „kleine“ Tabellen, oder Sie brauchen, um sie wirklich durch generato   eindeutige IDs von verschiedenen Orten (und nicht einen anderen Weg gefunden,   es zu tun). Mehr zu UUIDs: http://mysql.rjweb.org/doc.php/uuid (It   enthält Funktionen für zwischen 36 Standard-char UUIDs Umwandeln und   BINARY (16).)

     

, die sowohl eine UNIQUE AUTO_INCREMENT und eine einzigartige UUID in der gleichen   Tabelle ist eine Verschwendung.

     

Wenn ein INSERT auftritt, alle eindeutigen / Primärschlüssel muss geprüft werden   Duplikate. Entweder eindeutiger Schlüssel ist ausreichend für InnoDB Anforderung   der mit einem Primärschlüssel. Binary (16) (16 Bytes) ist etwas voluminös (ein   Argument dagegen die PK) zu machen, aber nicht so schlimm. die Sperrigkeit   ist wichtig, wenn Sie Sekundärschlüssel haben. InnoDB heftet leise die PK   auf das Ende eines jeden Sekundärschlüssel. Die wichtigste Lehre ist hier zu   die Anzahl der Sekundärschlüssel minimieren, vor allem für sehr große   Tabellen. Zum Vergleich: INT nicht signiert ist mit 4 Bytes Bereich von 0..4   Milliarde. BIGINT ist 8 Byte.

Bei meinem letzten Job, waren wir Objekte von Dritten erhalten, die eindeutig mit UUID identifiziert wurde. Ich habe in einer UUID-> Long-Integer-Lookup-Tabelle und verwenden long integer als meine primären Schlüssel, weil es war viel schneller auf diese Weise.

den Version 1-Algorithmus verwendet es scheint, dass es unmöglich Kollision unter der Einschränkung ist, dass weniger als 10 UUIDs pro Millisekunde aus der gleichen MAC-Adresse erzeugt

  

Konzeptionell ist die ursprüngliche (Version 1)   Erzeugungsschema für UUIDs war   verketten die UUID-Version mit der   MAC-Adresse des Computers, ist   Erzeugen des UUID und mit dem   Anzahl der 100-Nanosekunden-Intervalle   Seit der Annahme des Gregorianischen   Kalender im Westen. In der Praxis der   Ist Algorithmus ist komplizierter.   Dieses Schema wurde kritisiert in   dass es nicht ausreichend ‚opaque‘;   es zeigt sowohl die Identität des   Computer, der die UUID erzeugt und   der Zeitpunkt, an dem es so tat.

Jemand korrigiert mich wenn ich falsch interpretiert, wie es funktioniert

Die sagen, dass UUIDs schlechtes Design ist, weil sie könnte (irgend lächerlich geringe Wahrscheinlichkeit) kollidieren, während der DB Schlüssel generiert werden nicht ... Sie wissen, dass die Chance auf menschliches Versagen verursacht eine Kollision auf Ihrer DB generierten Schlüssel wegen einer un-forseen Notwendigkeit ist FAR FAR FAR höher als die Chance UUID4 Kollision. Wir wissen , wenn der db neu erstellt wird es wieder IDs bei 1 beginnen wird, und wie viele von uns einen Tisch mussten neu erstellt, wenn wir sicher waren, würden wir nie brauchen? Ich würde mein Geld auf UUID Sicherheit setzen, wenn Sachen jeden Tag schief gehen mit unbekanntem Unbekannten beginnt.

Abgesehen von Fällen, in denen Sie jemand anderes API verwenden, die eine UUID verlangt, natürlich gibt es immer eine andere Lösung. Aber werden diese Alternativen lösen alle die Probleme, die UUID tun? Werden Sie am Ende mehr Schichten von Hacks Zugabe, die jeweils ein anderes Problem zu lösen, wenn man alle von ihnen auf einmal gelöst haben?

Ja, es ist theoretisch möglich, UUIDs zu kollidieren. Wie andere bereits erwähnt haben, ist es lächerlich unwahrscheinlich bis zu dem Punkt, dass es angesichts einfach nicht wert ist. Es ist noch nie passiert, auf dem Laufenden und höchstwahrscheinlich nie. Vergessen Sie es.

Die „offensichtlich“ Art und Weise Kollisionen zu vermeiden, ist ein einzelner Server auf jedem Einsatz eindeutige IDs generieren zu lassen, was offensichtlich ernsthafte Performance-Probleme schafft und löst nicht das Offline-Generation Problem. Oops.

Die andere „offensichtlich“ Lösung ist eine zentrale Instanz, die Blöcke von eindeutigen Nummern vorab austeilt, die im Wesentlichen ist, was UUID V1 tut, indem die MAC-Adresse des erzeugenden Maschine (über den IEEE OUI). Aber doppelte MAC-Adressen passieren, da alle zentralen Behörde Schrauben bis schließlich, so in der Praxis viel wahrscheinlicher ist als eine UUID V4 Kollision. Oops.

Das beste Argument gegen UUIDs ist, dass sie die interessantesten Probleme „zu groß“, sondern eine (deutlich) kleine Regelung wird unweigerlich scheitern zu lösen sind; UUIDs' Größe ist ein inhärenter Nebeneffekt ihrer Nützlichkeit bei diesen sehr Probleme zu lösen.

Es ist möglich, Ihr Problem ist nicht groß genug zu müssen, was UUIDs bietet, und in diesem Fall, fühlen Sie sich frei, etwas anderes zu verwenden. Aber wenn Ihr Problem unerwartet wächst (und die meisten tun), werden Sie später Schalen am Ende - und treten selbst für sie nicht in erster Linie verwendet wird. Warum Design für das Scheitern, wenn es so einfach für den Erfolg zu entwerfen, statt?

UUIDs verkörpern all die schlechten Codierung Praktiken mit globalen Variablen verbunden sind, nur noch schlimmer, da sie superglobalen Variablen, die über verschiedene Stücke Kit verteilt werden können.

getroffen Kürzlich solche ein Problem mit dem Austausch eines Druckers mit einem genauen Ersatzmodell, und stellte fest, dass keine der Client-Software funktionieren würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top