Klasyczna baza może przydzielać kolejne numery, jeśli każdy nowy rekord najpierw do niej trafia. W systemie rozproszonym klient mobilny, importer i kilka usług często potrzebują tożsamości jeszcze przed centralnym insertem. UUID rozwiązuje właśnie problem przydziału: uczestnicy generują wartości samodzielnie w ogromnej przestrzeni, bez rezerwowania numeru u jednego koordynatora.

UUID ma 128 bitów

Znana postać tekstowa zawiera 32 znaki hex podzielone myślnikami, na przykład 550e8400-e29b-41d4-a716-446655440000. Sam identyfikator zajmuje 16 bajtów. Część bitów opisuje version i variant, a pozostałe zależą od metody generowania.

API powinno zwracać jedną postać kanoniczną. Baza może używać natywnego typu UUID lub binarnego pola, co zmniejsza storage i index względem ogólnego stringa.

Ogromna przestrzeń zastępuje rezerwację

W losowym UUIDv4 po odjęciu bitów strukturalnych pozostają 122 bity losowości. Przy poprawnym generatorze ryzyko przypadkowej kolizji jest praktycznie bardzo małe nawet dla wielkich zbiorów. Jest to gwarancja probabilistyczna, ale wystarczająco silna dla typowych systemów.

Obiekt może otrzymać ID offline, pojawić się w eventach i relacjach, a dopiero później trafić do wspólnej bazy. Niezależne zbiory łatwiej łączyć bez remapowania sekwencji.

Jakość generatora nadal ma znaczenie

Duża przestrzeń nie pomoże, jeśli wadliwy random generator powtarza sekwencję po klonowaniu maszyny. Należy używać utrzymywanych bibliotek opartych na systemowym źródle kryptograficznej losowości.

Własna konstrukcja z timestampu, PID i krótkiego randomu zmniejsza entropię i może ujawniać informacje. Duplicate-key należy traktować jako możliwy błąd generatora lub retry, nie automatycznie jako astronomiczny przypadek.

Wersje oferują różne właściwości

UUIDv4 jest w większości losowy. UUIDv7 łączy czas unixowy z losowością, dzięki czemu wartości są w przybliżeniu sortowalne. Wersje name-based dają ten sam wynik dla tego samego namespace i name.

Kontrakt powinien określać, co system generuje i jakie wersje akceptuje. Długi string nie jest wystarczającym opisem semantyki.

Niezależna generacja zmienia workflow

Klient może nadać ID przed uploadem i używać go w każdym retry. Pomaga to w idempotentnym tworzeniu oraz budowaniu relacji między nowymi obiektami bez czekania na odpowiedź bazy.

Jeżeli retry za każdym razem generuje nową UUID, nadal powstają duplikaty biznesowe. Tożsamość intencji musi pozostać stabilna.

UUID nie jest sekretem

Losowej wartości trudno się domyślić, ale pojawia się w URL, logach i wiadomościach supportu. Endpoint musi sprawdzić użytkownika, tenant i akcję dla każdego ID. Wiedza o identyfikatorze nie oznacza prawa dostępu.

Capability link powinien używać osobnego tokena z expiry i revocation. Trwała tożsamość zasobu ma inny lifecycle niż credential.

Publiczne i wewnętrzne ID mogą współistnieć

Baza może mieć sekwencyjny primary key dla joinów i UUID dla API. Pozwala to osobno optymalizować storage oraz publiczny kontrakt. Nie jest jednak obowiązkowe i dodaje mapowanie.

Nazwy pól oraz typy muszą wyraźnie odróżniać oba identyfikatory. Ich pomylenie prowadzi do złych relacji i błędów autoryzacji.

Postać tekstowa wymaga normalizacji

Hex może mieć inną wielkość liter, a część parserów przyjmuje formę bez myślników lub z nawiasami. Wewnętrzna wartość może być taka sama. API powinno parsować biblioteką i zawsze emitować canonical text.

Nie wolno „naprawiać” uciętych lub rozszerzonych stringów. Alternatywna legalna reprezentacja może zostać znormalizowana, a niepoprawna tożsamość odrzucona.

Index zależy od wersji i silnika bazy

Losowy UUIDv4 w uporządkowanym B-tree powoduje inserty w wielu miejscach. Przy dużym write load zwiększa to page splits, I/O i fragmentację. Skala efektu zależy od engine oraz schematu.

UUIDv7 albo sekwencyjny klucz wewnętrzny może poprawić locality. Decyzję należy mierzyć na rzeczywistych insertach, joinach, replikacji i backupie.

Sortowalność nie zastępuje pola czasu

Część czasowa v7 pochodzi z zegara producenta. Clock skew i wiele wartości w tej samej milisekundzie pozostają możliwe. Do audytu oraz biznesowej daty nadal potrzebne jest created_at.

UUID może optymalizować indeks i przybliżoną kolejność, ale nie powinien stać się ukrytym źródłem wszystkich informacji domenowych.

Migracja potrzebuje trwałego mappingu

Podczas importu ten sam rekord źródłowy nie może za każdym uruchomieniem otrzymywać nowej UUID. Tabela source system, external ID i internal UUID zapewnia deterministyczne retry oraz zachowuje relacje.

Istniejących opublikowanych identyfikatorów zwykle nie warto przepisywać. Nowa wersja generatora może obowiązywać wyłącznie dla kolejnych rekordów.

Offline-first korzysta ze stabilnej tożsamości przed synchronizacją

Aplikacja terenowa może utworzyć klienta, zdjęcia i notatki bez połączenia z serwerem. Lokalne rekordy otrzymują UUID, dzięki czemu ich relacje nie wymagają tymczasowych ujemnych numerów ani późniejszego przepisywania wszystkich odwołań. Po synchronizacji serwer zachowuje tę samą tożsamość.

Konflikt nadal wymaga rozwiązania. Dwa urządzenia mogą niezależnie opisać ten sam realny obiekt różnymi UUID. Deduplication i reguły łączenia są problemem domenowym, którego generator nie wykryje.

Eventy potrzebują rozróżnienia ID zasobu i wiadomości

Identyfikator zamówienia nie powinien automatycznie pełnić roli identyfikatora każdego eventu o tym zamówieniu. Osobne event ID wspiera deduplication delivery, a resource ID łączy historię. Correlation ID może dodatkowo grupować cały workflow.

Jawne nazwy zapobiegają sytuacji, w której consumer odrzuca legalne kolejne zdarzenie, ponieważ uznał UUID zasobu za klucz idempotency wiadomości.

UUID rozwiązuje przydział, nie cały model

Unique constraints, foreign keys, authorization, idempotency i retencja nadal są potrzebne. UUID usuwa centralny licznik i umożliwia tożsamość przed zapisem.

Dobry kontrakt opisuje version, generator, canonical form, typ bazy i lifecycle. Wtedy identyfikator pozostaje niezawodnym narzędziem, a nie przypadkowym długim stringiem.