Kiedy naprawdę jesteś zmuszony do używania UUID jako części projektu?

Nie widzę sensu UUID . Wiem, że prawdopodobieństwo kolizji wynosi efektywnie zero , ale efektywnie zero nie jest nawet bliskie niemożliwości.

Czy ktoś może podać przykład, w którym nie ma innego wyjścia jak użyć UUID? Ze wszystkich zastosowań, które widziałem, widzę alternatywny projekt bez UUID. Oczywiście projekt może być nieco bardziej skomplikowany, ale przynajmniej nie ma niezerowego prawdopodobieństwa awarii.

UUID pachnie jak zmienne globalne. Istnieje wiele sposobów, w jaki zmienne globalne ułatwiają projektowanie, ale jest to po prostu leniwy projekt.

Author: Machavity, 2009-03-31

16 answers

Napisałem generator / parser uuid dla Rubiego, więc uważam się za dość dobrze poinformowanego na ten temat. Istnieją cztery główne wersje UUID:

Uuid w wersji 4 to w zasadzie 16 bajtów losowości pobranych z zabezpieczonego kryptograficznie generatora liczb losowych, z pewnym przekręcaniem bitów w celu identyfikacji wersji i wariantu UUID. Są bardzo mało prawdopodobne, aby zderzyć się, ale może się zdarzyć, jeśli PRNG jest używany lub jeśli po prostu masz naprawdę, naprawdę, naprawdę, naprawdę, naprawdę pech.

W wersji 5 I 3 uuid używają odpowiednio funkcji skrótu SHA1 i MD5, aby połączyć przestrzeń nazw z fragmentem już unikalnych danych w celu wygenerowania UUID. Pozwoli to na przykład utworzyć UUID z adresu URL. Kolizje tutaj są możliwe tylko wtedy, gdy podstawowa funkcja hash ma również kolizję.

UID w wersji 1 są najczęściej spotykane. Używają adresu MAC karty sieciowej (który, o ile nie jest sfałszowany, powinien być unikalny), Plus znacznik czasu, plus Zwykle bit-twidling do generowania UUID. W przypadku maszyny, która nie ma adresu MAC, bajty 6 węzłów są generowane za pomocą zabezpieczonego kryptograficznie generatora liczb losowych. Jeśli dwa uuid są generowane w kolejności na tyle szybko, że znacznik czasu pasuje do poprzedniego UUID, znacznik czasu jest zwiększany o 1. Kolizje nie powinny wystąpić, chyba że wystąpi jedna z następujących sytuacji: adres MAC jest sfałszowany; jedna maszyna z dwoma różnymi aplikacjami generującymi UUID wytwarza uuid na dokładnie w tym samym momencie; dwie maszyny bez karty sieciowej lub bez dostępu użytkownika do adresu MAC otrzymują tę samą losową sekwencję węzłów i generują uuid dokładnie w tym samym momencie; kończą nam się bajty, aby reprezentować znacznik czasu i rollover z powrotem do zera.

Realistycznie, żadne z tych zdarzeń nie występuje przypadkowo w przestrzeni ID pojedynczej aplikacji. Chyba że akceptujesz identyfikatory na przykład w skali internetowej lub w niezaufanym środowisku, w którym mogą znajdować się złośliwe osoby w stanie zrobić coś złego w przypadku kolizji ID, to po prostu nie jest coś, o co powinieneś się martwić. Ważne jest, aby zrozumieć, że jeśli zdarzy ci się wygenerować ten sam UUID w wersji 4, co ja, w większości przypadków, nie ma to znaczenia. Wygenerowałem identyfikator w zupełnie innym miejscu niż twój. Moja aplikacja nigdy nie dowie się o kolizji, więc kolizja nie ma znaczenia. Szczerze mówiąc, w jednej przestrzeni aplikacji bez złośliwych aktorów, nastąpi wymarcie całego życia na ziemi na długo przed kolizją, nawet na UUID w wersji 4, nawet jeśli generujesz sporo uuid na sekundę.

Również, 2^64 * 16 to 256 eksabajtów. Aby mieć 50% szans na kolizję identyfikatorów w pojedynczej przestrzeni aplikacji, konieczne jest przechowywanie identyfikatorów o wartości 256 eksabajtów.

 631
Author: Bob Aman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-09 18:24:26

Rzeczą, którą kupują Ci uuid, która jest bardzo trudna do zrobienia w inny sposób, jest uzyskanie unikalnego identyfikatora bez konieczności konsultacji lub koordynacji z centralnym organem . Ogólny problem możliwości uzyskania czegoś takiego bez jakiejś zarządzanej infrastruktury jest problemem, który rozwiązują uuid.

Czytałem, że zgodnie z paradoksem urodzinowym szansa na kolizję UUID wynosi 50% po wygenerowaniu 2^64 uuid. Teraz 2^64 to dość duża liczba, ale 50% szans na kolizję wydaje się zbyt ryzykowne (na przykład, ile uuid musi istnieć, zanim istnieje 5% szansy na kolizję - nawet to wydaje się zbyt duże prawdopodobieństwo).

Problem z tą analizą jest dwojaki:

  1. Uuid nie są całkowicie losowe - istnieją główne składniki UUID, które są oparte na czasie i / lub lokalizacji. Aby mieć realną szansę na kolizję, zderzające się uuid muszą być generowane dokładnie w tym samym czasie z różnych UUID Generatory. Powiedziałbym, że chociaż istnieje rozsądna szansa, że kilka UUID może być generowanych w tym samym czasie, jest wystarczająco dużo innych gunk (w tym informacje o lokalizacji lub losowe bity), aby podobieństwo do kolizji między tym bardzo małym zestawem uuid prawie niemożliwe.

  2. Ściśle mówiąc, uuid muszą być unikalne tylko wśród zestawu innych uuid, z którymi mogą być porównywane. Jeśli generujesz UUID do użycia jako klucz bazy danych, nie ma znaczenia, czy gdzieś w innym złym alternatywnym wszechświecie ten sam UUID jest używany do identyfikacji interfejsu komunikacyjnego. Tak jak to nie spowoduje zamieszania, jeśli jest ktoś (lub coś) o imieniu "Michael Burr" Na Alpha-Centauri.

 72
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:49:14

Wszystko ma niezerową szansę na porażkę. Skupiłbym się na znacznie bardziej prawdopodobnych problemach (tj. prawie wszystkim, o czym możesz pomyśleć) niż kolizja UUIDs

 35
Author: DanSingerman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-03 13:35:11

Nacisk na "rozsądnie" lub, jak to ująłeś, "skutecznie": wystarczająco dobre jest to, jak działa prawdziwy świat. Ilość pracy obliczeniowej związanej z pokryciem tej luki między "praktycznie unikalnym" a "naprawdę unikalnym" jest ogromna. Wyjątkowość to krzywa o malejących zwrotach. W pewnym momencie na tej krzywej znajduje się granica między tym, gdzie "wystarczająco unikalny" jest nadal niedrogi, a następnie krzywimy się bardzo stromo. Koszt dodania większej wyjątkowości staje się dość duży. Nieskończona wyjątkowość ma nieskończoną koszt.

Uuid/GUID jest stosunkowo szybkim i łatwym obliczeniowo sposobem generowania ID, które może być racjonalnie uznane za uniwersalnie unikalne. Jest to bardzo ważne w wielu systemach, które muszą integrować dane z wcześniej niepowiązanych systemów. Na przykład: jeśli masz System Zarządzania Treścią, który działa na dwóch różnych platformach, ale w pewnym momencie musisz zaimportować zawartość z jednego systemu do drugiego. Nie chcesz zmieniać identyfikatorów, więc twoje referencje pomiędzy danymi z systemu A pozostają nienaruszone, ale nie chcesz żadnych kolizji z danymi utworzonymi w systemie B. UUID rozwiązuje to.

 16
Author: Rex M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:06:18

Tworzenie UUID nigdy nie jest absolutnie konieczne. Jest to jednak wygodne, aby mieć standard, w którym offline użytkownicy mogą wygenerować klucz do czegoś o bardzo niskim prawdopodobieństwie kolizji.

Może to pomóc w rozwiązywaniu replikacji bazy danych itp...

Byłoby łatwo dla użytkowników online wygenerować unikalne klucze do czegoś bez narzutu lub możliwości kolizji, ale nie do tego służą uuid.

Anyway, a word on the prawdopodobieństwo kolizji, zaczerpnięte z Wikipedii:

Aby ująć te liczby w perspektywie, jedno roczne ryzyko uderzenia przez meteoryt jest szacowana na jedną szansę na 17 miliardów, równoważne aby stworzyć kilkadziesiąt bilionów Uuidów w ciągu roku i posiadanie jednego duplikatu. Innymi słowy, dopiero po wygenerowaniu 1 miliarda UUIDs co sekundę przez następne 100 lat, prawdopodobieństwo stworzenia jeden duplikat to około 50%.

 16
Author: John Gietzen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-31 10:25:44

Istnieje również niezerowe prawdopodobieństwo, że każda cząstka w twoim ciele będzie jednocześnie tunelować przez krzesło, na którym siedzisz i nagle znajdziesz się na podłodze.

Martwisz się o to?

 14
Author: user21714,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 22:32:23

Klasycznym przykładem jest replikacja pomiędzy dwoma bazami danych.

DB(A) wstawia rekord o ID int 10 i jednocześnie DB(B) tworzy rekord o ID 10. To kolizja.

Z uuid to się nie stanie, ponieważ nie będą pasować. (prawie na pewno)

 13
Author: Johnno Nolan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:05:03

Mam schemat unikania Uuidów. Skonfiguruj gdzieś serwer i miej go tak, że za każdym razem, gdy jakiś program chce uniwersalnie unikalnego identyfikatora, kontaktuje się z tym serwerem, a on go rozdaje. Proste!

Z wyjątkiem tego, że są z tym prawdziwe praktyczne problemy, nawet jeśli ignorujemy jawną złośliwość. W szczególności serwer ten może zawieść lub stać się niedostępny z części Internetu. Radzenie sobie z awarią serwera wymaga replikacji, a to jest bardzo trudne do popraw się (zobacz literaturę na temat algorytmu Paxos, aby dowiedzieć się, dlaczego budowanie konsensusu jest niezręczne) i jest również dość powolne. Co więcej, jeśli wszystkie serwery są nieosiągalne z określonej części ' sieci, żaden z klientów podłączonych do tej podsieci nie będzie w stanie nic zrobić, ponieważ wszyscy będą czekać na nowe identyfikatory.

Więc... użyj prostego algorytmu probabilistycznego, aby wygenerować je, które prawdopodobnie nie zawiodą podczas życia ziemi lub (sfinansuj i) zbuduj dużą infrastrukturę to będzie pita rozmieszczenia i mają częste awarie. Wiem, na którą bym się wybrał.

 8
Author: Donal Fellows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 09:04:23

Nie rozumiem całej rozmowy o prawdopodobieństwie kolizji. Nie obchodzi mnie kolizja. Ale zależy mi na wydajności.

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

Uuid są katastrofą wydajności dla bardzo dużych tabel. (200k wierszy to nie "bardzo duży".)

Twój # 3 jest naprawdę zły, gdy zestaw CHARCTERA to utf8 -- CHAR (36) zajmuje 108 bajtów!

UUIDs (GUIDs) są bardzo "przypadkowe". Używanie ich jako unikalnego lub Klucz podstawowy na dużych stołach jest bardzo nieefektywny. Jest to spowodowane konieczność przeskakiwania po tabeli / indeksie za każdym razem, gdy wstawiasz nowy UUID lub wybierz przez UUID. Gdy tabela / indeks jest zbyt duża, aby zmieścić się w pamięci podręcznej (patrz innodb_buffer_pool_size, który musi być mniejszy niż RAM, zazwyczaj 70%), "następny" UUID może nie być buforowany, stąd wolny dysk hit. Gdy tabela / indeks jest 20 razy większy od bufora, tylko 1/20 (5%) odsłon są buforowane - jesteś związany We / Wy.

Więc nie używaj UUIDs chyba że

Masz" małe " tabele, lub naprawdę ich potrzebujesz ze względu na generowanie unikalne identyfikatory z różnych miejsc (i nie wymyślili innego sposobu aby to zrobić). Więcej o UUIDs: http://mysql.rjweb.org/doc.php/uuid (It zawiera funkcje do konwersji pomiędzy standardowymi 36-znakowymi uuid i BINARY (16))

Posiadanie zarówno unikalnego AUTO_INCREMENT, jak i unikalnego UUID w tym samym stół to marnotrawstwo.

Gdy występuje wstawka, wszystkie klucze unique / primary muszą być sprawdzone pod kątem duplikaty. Każdy unikalny klucz jest wystarczający dla wymagań InnoDB o posiadaniu klucza głównego. BINARY(16) (16 bajtów) jest nieco nieporęczny (an argument przeciw zrobieniu z niego PK), ale nie aż tak źle. The bulkiness ma znaczenie, gdy masz dodatkowe klucze. InnoDB na końcu każdego klucza wtórnego. Główną lekcją jest zminimalizować liczbę klawiszy dodatkowych, szczególnie w przypadku bardzo dużych stoły. Dla porównania: INT UNSIGNED to 4 bajtów z zakresem 0..4 / align = "left" / BIGINT to 8 bajtów.

 5
Author: Toskan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:42:36

Jeśli po prostu spojrzysz na alternatywy np. dla prostej aplikacji bazodanowej, aby za każdym razem przed utworzeniem nowego obiektu zadać zapytanie do bazy danych, wkrótce przekonasz się, że użycie UUID może skutecznie zredukować złożoność Twojego systemu. Przyznane - jeśli używasz kluczy int, są to 32bit, które będą przechowywać w jednej czwartej 128-bitowego UUID. Algorytmy generowania Granted-UUID zajmują więcej mocy obliczeniowej niż zwykłe zwiększanie liczby. Ale kogo to obchodzi? Narzuty zarządzania "upoważnienie" do przypisywania unikalnych liczb łatwo przewyższa to rzędami wielkości, w zależności od zamierzonego miejsca identyfikatora unikalności.

 4
Author: Mirko Klemm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-26 15:47:14

On UUID= = lazy design

Nie zgadzam się z tym, że chodzi o wybieranie Twoich walk. Jeśli duplikat UUID jest statystycznie niemożliwy, a matematyka jest udowodniona, to po co się martwić? Spędzanie czasu na projektowaniu wokół swojego małego systemu generującego N UUID jest niepraktyczne, zawsze istnieje kilkanaście innych sposobów na ulepszenie systemu.

 3
Author: Johnno Nolan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:52:06

W mojej ostatniej pracy otrzymywaliśmy przedmioty od osób trzecich, które zostały jednoznacznie zidentyfikowane z UUID. Umieściłem w tabeli wyszukiwania uuid - > long integer i użyłem long integer jako moich kluczy głównych, ponieważ było to o wiele szybsze w ten sposób.

 1
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:04:22

Używając algorytmu w wersji 1 wydaje się, że jest to niemożliwe pod warunkiem, że z tego samego adresu MAC generowanych jest mniej niż 10 uuid na milisekundę

Koncepcyjnie, oryginał (Wersja 1) system generowania Uuidów miał na celu połącz wersję UUID z Adres MAC komputera, który jest generowanie UUID, a wraz z Liczba 100-nanosekundowych interwałów od przyjęcia gregoriańskiego kalendarz na Zachodzie. W practice, the rzeczywisty algorytm jest bardziej skomplikowany. Program ten został skrytykowany w że nie jest wystarczająco "nieprzezroczysta"; ujawnia zarówno tożsamość komputer, który wygenerował UUID i czas, w którym to się stało.

Ktoś mnie poprawi jeśli źle zinterpretuję jak to działa

 1
Author: Davy8,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-31 21:23:58

Do tych, którzy mówią, że uuid są złym projektem, ponieważ Mogą (z jakimś śmiesznie małym prawdopodobieństwem) zderzyć się, podczas gdy klucze generowane przez DB nie będą... wiesz, że szansa, że błąd człowieka spowoduje kolizję na kluczach generowanych przez DB z powodu jakiejś nieusuwalnej potrzeby, jest o wiele większa niż szansa na kolizję UUID4. Wiemy , że jeśli db zostanie odtworzone, to uruchomi identyfikatory od 1 ponownie, i ilu z nas musiało odtworzyć tabelę, gdy byliśmy pewni, że nigdy musisz? Postawiłbym na bezpieczeństwo UUID, gdy coś pójdzie nie tak z nieznanymi-nieznanymi.

 1
Author: Iain Duncan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 21:24:02

Poza przypadkami, w których musisz użyć cudzego API, które wymaga UUID, zawsze jest inne rozwiązanie. Ale czy te alternatywy rozwiążą wszystkie problemy, które robią UUIDs? Czy w końcu dodasz więcej warstw hacków, z których każda rozwiązuje inny problem, kiedy mogłeś rozwiązać je wszystkie na raz?

Tak, teoretycznie możliwe jest zderzenie Uuidów. Jak zauważyli inni, jest śmiesznie mało prawdopodobne do tego stopnia, że po prostu nie warto biorąc pod uwagę. To się nigdy nie zdarzyło i najprawdopodobniej nigdy nie będzie. Zapomnij o tym.

Najbardziej "oczywistym" sposobem uniknięcia kolizji jest umożliwienie pojedynczemu serwerowi generowania unikalnych identyfikatorów na każdej wkładce, co oczywiście stwarza poważne problemy z wydajnością i nie rozwiązuje problemu generowania offline. UPS.

Innym "oczywistym" rozwiązaniem jest organ centralny, który z góry rozdaje bloki unikalnych numerów, co zasadniczo robi UUID V1 za pomocą komputera MAC adres maszyny generującej (poprzez IEEE OUI). Ale duplikaty adresów MAC zdarzają się, ponieważ każdy organ centralny w końcu spieprza, więc w praktyce jest to znacznie bardziej prawdopodobne niż kolizja UUID V4. UPS.

Najlepszym argumentem przeciwko używaniu uuid jest to, że są "zbyt duże", ale (znacznie) mniejszy schemat nieuchronnie nie rozwiąże najciekawszych problemów; rozmiar uuid jest nieodłącznym efektem ubocznym ich przydatności w rozwiązywaniu tych bardzo problemy.

Jest możliwe, że twój problem nie jest wystarczająco duży, aby potrzebować tego, co oferują UUIDs, i w takim przypadku możesz użyć czegoś innego. Ale jeśli twój problem rośnie nieoczekiwanie (i większość robi), skończysz później przełączać-i kopać się za to, że nie używasz ich w pierwszej kolejności. Po co projektować na niepowodzenie, skoro tak łatwo jest zaprojektować na sukces?

 0
Author: StephenS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-31 22:24:13

Uuid uosabiają wszystkie złe praktyki kodowania związane ze zmiennymi globalnymi, tylko gorzej, ponieważ są to zmienne superglobalne, które mogą być rozłożone na różne kawałki zestawu.

Ostatnio napotkał taki problem z wymianą drukarki na dokładny model zastępczy I stwierdził, że żadne oprogramowanie klienckie nie będzie działać.

 -11
Author: John Doe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-12 07:22:30