Struktura i losowość identyfikatora UUID v4
Generator UUID v4 na tej stronie tworzy identyfikatory oparte na 122 bitach czystej losowości. Każdy wygenerowany ciąg to 36 znaków w standardowym formacie 8‑4‑4‑4‑12, co daje łącznie 32 znaki szesnastkowe plus 4 łączniki. Sześć bitów w każdym UUID jest stałych: 4 bity oznaczają wersję („0100” dla wersji 4), a 2 bity to wariant („10”). Pozostałe 122 bity pochodzą z kryptograficznie bezpiecznego źródła losowości w przeglądarce, zwykle z API crypto.randomUUID lub równoważnego mechanizmu.
Stałe bity wersji i wariantu są wymagane przez specyfikację RFC 4122. Bez nich identyfikator nie mógłby być jednoznacznie rozpoznany jako UUID v4 przez żadne oprogramowanie zgodne ze standardem. Dlatego nawet po wyłączeniu łączników w ustawieniach narzędzia – co skraca ciąg do 32 znaków – nadal obowiązuje ta sama wewnętrzna struktura bitowa. Zmiana wielkości liter (a–f na A–F) dotyczy wyłącznie reprezentacji wizualnej; wartość binarna pozostaje taka sama.
Forma z łącznikami (xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, gdzie x to losowa cyfra szesnastkowa, a y to jeden z bitów wariantu) jest kanoniczna i zalecana przez RFC. Bez łączników identyfikator traci czytelność, ale zachowuje wszystkie 122 bity entropii. Użycie wielkich liter nie wpływa na interoperacyjność – większość systemów normalizuje UUID do małych liter przed porównaniem.
Prawdopodobieństwo kolizji i 122 bity entropii
Praktyczne znaczenie 122 bitów losowości polega na astronomicznie niskim prawdopodobieństwie wygenerowania dwóch identycznych UUID v4. Według klasycznej analizy prawdopodobieństwa kolizji (problemu urodzinowego), aby osiągnąć 50% szans na kolizję, trzeba by wygenerować około 2,71 × 10^18 identyfikatorów. Dla porównania: gdyby każdy z 8 miliardów ludzi na Ziemi generował miliard UUID na sekundę, pierwsza kolizja wystąpiłaby średnio po kilkudziesięciu latach ciągłej pracy.
To sprawia, że UUID v4 nadaje się do systemów rozproszonych, w których węzły nie mogą komunikować się ze sobą przy każdym tworzeniu identyfikatora. Klient mobilny, serwer w trybie offline, mikrousługa bez dostępu do centralnego rejestru – każdy z nich może wygenerować unikalny klucz bez ryzyka konfliktu.
W praktyce inżynierskiej prawdopodobieństwo kolizji jest tak niskie, że można je pominąć nawet w systemach z miliardami rekordów. Jednak projektanci systemów krytycznych (np. rejestry transakcji finansowych) czasem dodają dodatkowy unikalny indeks lub używają identyfikatorów sekwencyjnych, by wyeliminować nawet teoretyczne ryzyko. W większości zastosowań sieciowych, baz danych NoSQL i systemów zdarzeniowych UUID v4 jest standardem.
Wpływ na indeksowanie w bazach danych
Największym kosztem używania UUID v4 jako klucza głównego w relacyjnych bazach danych jest fragmentacja indeksów B‑drzew. Identyfikatory v4 są całkowicie losowe – nie niosą informacji o czasie ani o żadnym naturalnym porządku. Gdy nowy wiersz trafia do tabeli, jego klucz UUID v4 może pojawić się w dowolnym miejscu drzewa indeksu, zamiast w uporządkowanym bloku na końcu.
W praktyce oznacza to, że każda operacja INSERT może powodować rozdzielenie strony indeksu (page split), co prowadzi do:
- Zwiększonego użycia pamięci podręcznej (bufory stron muszą pomieścić rozproszone bloki).
- Wyższego narzutu operacji wejścia/wyjścia na dysku.
- Niższej gęstości upakowania w indeksie – strony są wypełnione średnio w około 50% zamiast 80–90%.
- Częstszej potrzeby reorganizacji indeksu (reindex) w dłuższym okresie.
Kontrastuje to z identyfikatorami czasowymi, takimi jak UUID v7, ULID czy sekwencyjne wartości autoinkrementowane, które powodują, że nowe wpisy trafiają do ostatniej strony indeksu, minimalizując fragmentację. Różnica staje się znacząca przy tabelach liczących miliony wierszy i wysokiej współbieżności zapisów.
Inżynierowie baz danych często stosują kompromis: używają UUID v4 jako klucza aplikacyjnego (business key) w systemach rozproszonych, ale jako klucz główny (primary key, clustered index) stosują dodatkową kolumnę sekwencyjną. W bazach NoSQL (np. Cassandra, MongoDB) fragmentacja indeksów ma mniejsze znaczenie, bo struktury danych są inaczej projektowane.
Porównanie z identyfikatorami czasowymi: UUID v7, ULID, NanoID
Narzędzie na tej stronie pozwala wybrać format UUID, co ułatwia zestawienie właściwości różnych typów identyfikatorów. UUID v4 jest jedynym w pełni losowym standardowym UUID (obok v3 i v5, które są deterministyczne i oparte na skrótach). UUID v7, wprowadzony w RFC 9562, zawiera znacznik czasu Unix (milisekundy) w pierwszych 48 bitach, co czyni go częściowo sortowalnym. ULID (Universally Unique Lexicographically Sortable Identifier) również łączy czas i losowość, ale w innym układzie bitów. NanoID z kolei używa większego alfabetu (A-Za-z0-9_-), co przy tej samej długości daje wyższą entropię na znak.
Różnice kluczowe:
| Cecha | UUID v4 | UUID v7 | ULID | NanoID |
|---|---|---|---|---|
| Losowość | 122 bity | 74 bity | 80 bitów | zmienna (zwykle ~126 bitów dla 21 znaków) |
| Sortowalność | Brak | Częściowa (czas) | Pełna leksykograficzna | Brak |
| Długość | 36 znaków (z łącznikami) | 36 znaków | 26 znaków | 21 znaków |
| Zależność od czasu | Nie | Tak | Tak | Nie |
Wybór między nimi zależy od priorytetów: jeśli priorytetem jest brak korelacji czasowej (np. w API tokenach, gdzie czas generowania nie powinien być odczytywany), UUID v4 jest lepszy. Jeśli priorytetem jest wydajność indeksów i częściowa możliwość sortowania, UUID v7 lub ULID mogą być korzystniejsze.
Przypadki użycia i kiedy unikać UUID v4
UUID v4 sprawdza się w sytuacjach, gdzie nie ma centralnego autorytetu nadającego identyfikatory: systemy rozproszone, architektura mikroserwisów, aplikacje offline działające na wielu urządzeniach, generowanie kluczy sesji i tokenów API. Losowość uniemożliwia odgadnięcie kolejnych identyfikatorów przez atakującego, co chroni przed enumeracją zasobów (np. /users/1234 -> /users/1235). To samo utrudnia też oszacowanie całkowitej liczby rekordów w systemie, co może być istotne w aplikacjach SaaS.
Należy unikać UUID v4 w systemach, gdzie wymagane jest sortowanie po dacie utworzenia (np. w newsfeedach, logach, kolejnych wersjach dokumentów) bez dodatkowej kolumny czasowej. Również w systemach OLTP z bardzo dużą częstotliwością insertów (ponad 10 tysięcy na sekundę) użycie sekwencyjnego klucza głównego może być konieczne dla utrzymania wydajności. W tych przypadkach lepiej sprawdza się UUID v7, ULID lub zwykły autoinkrement.
Dla bezpieczeństwa: UUID v4 zapewnia 122 bity losowości, co teoretycznie daje odporność na zgadywanie, ale nie zastępuje prawdziwych mechanizmów autoryzacji. Tokeny API generowane jako UUID v4 powinny być sprawdzane po stronie serwera i łączone z sesją użytkownika.
Dostosowywanie formatu i generowanie po stronie klienta
Przełączniki wielkości liter i łączników są specyficzne dla UUID v4 (i v7). Dla innych identyfikatorów (ULID, NanoID) narzędzie używa innych kontrolek. Wyłączenie łączników tworzy 32‑znakowy ciąg szesnastkowy, który jest bardziej zwarty i nadaje się do osadzania w URL-ach bez konieczności kodowania procentowego. Jednak traci się wtedy standardowe grupowanie, co utrudnia ręczne odczytywanie i kopiowanie.
Włączenie wielkich liter (A–F) może być potrzebne przy integracji z systemami, które wymagają konkretnej wielkości liter (np. niektóre starsze systemy mainframe). W przeciwnym razie równie dobrze działa domyślny zapis małymi literami.
Wszystkie generacje odbywają się lokalnie w przeglądarce – żadne dane nie są wysyłane na serwer. To ma znaczenie przy generowaniu identyfikatorów dla danych wrażliwych (np. klucze szyfrowania, identyfikatory pacjentów). Brak opóźnienia sieciowego powoduje, że nawet 100 UUID jest generowanych błyskawicznie, bez oczekiwania na odpowiedź serwera.
Najczęściej zadawane pytania (FAQ)
Czy UUID v4 jest bezpieczniejszy niż UUID v7 pod względem kryptograficznym?
Oba są generowane z kryptograficznie bezpiecznego źródła losowości, ale UUID v4 ukrywa czas generowania, co może utrudnić ataki oparte na przewidywaniu (timing attacks). Dla zwykłych tokenów API różnica jest pomijalna.
Czy mogę użyć UUID v4 jako klucza głównego w PostgreSQL?
Tak, ale rozważ użycie indeksu nieklastrowanego (non‑clustered) lub dodatkowego klucza sekwencyjnego, jeśli zapisy są bardzo częste. W PostgreSQL typ UUID jest natywny i dobrze zoptymalizowany.
Dlaczego liczba znaków wynosi 36, a nie 32 lub 38?
32 znaki szesnastkowe plus 4 łączniki = 36 znaków. Bez łączników liczba wynosi 32. Żaden standard nie definiuje 38‑znakowego UUID.
Czy istnieje ryzyko wygenerowania dwóch identycznych UUID v4 na tej stronie?
Teoretyczne ryzyko istnieje, ale jest tak małe, że w praktyce się nie zdarza. Generator używa silnego źródła losowości, które spełnia wymagania RFC 4122.
Czy mogę skopiować pojedynczy UUID z listy zamiast całej grupy?
Tak, kliknięcie w dowolny identyfikator na liście kopiuje go do schowka. Przycisk „Kopiuj wszystkie” kopiuje całą listę.
Co się stanie, jeśli ustawię liczbę na 0 lub więcej niż 100?
Generator akceptuje tylko wartości od 1 do 100 włącznie. Wprowadzenie wartości spoza tego zakresu nie wygeneruje identyfikatorów, a interfejs nie zmieni się.