Egyetlen adatbázisban könnyű azonosítót készíteni: a következő rekord megkapja a következő egész számot. A probléma akkor válik érdekessé, amikor mobilalkalmazás offline hoz létre objektumot, több régió egyszerre fogad kéréseket, vagy két vállalat később egyesíti az adatait. Közös számláló nélkül honnan tudhatja minden résztvevő, hogy nem ugyanazt az értéket választja? A UUID erre nem abszolút matematikai bizonyosságot, hanem olyan nagy azonosítóteret és generálási szabályokat kínál, amelyek mellett az ütközés a gyakorlatban rendkívül valószínűtlen.

Az azonosító nem ugyanaz, mint a sorszám

A sorszám sorrendet és gyakran üzleti jelentést sugall. A UUID elsődleges célja ezzel szemben az identitás: két külön létrehozott objektum külön értéket kapjon akkor is, ha készítőik nem beszélnek egymással. Nem mondja meg automatikusan, melyik rekord régebbi, fontosabb vagy melyik tenant tulajdona.

Ez a szétválasztás hasznos. A rendelés kaphat belső UUID-t és ettől független, ügyfélnek mutatott rendelési számot. Az egyik stabil technikai kapcsolatokat tart fenn, a másik az üzleti szabályok szerint formázható, újraindítható vagy országonként eltérhet.

A 128 bit hatalmas névteret ad

Egy UUID 128 bites érték, amelyet hagyományosan hexadecimális számjegyekkel és kötőjelekkel írunk le. A verzió- és variánsmezők néhány bitet lefoglalnak, de a fennmaradó tér még mindig óriási. Véletlen alapú UUID esetén nem minden új értéket hasonlítunk össze a világ összes korábbi azonosítójával; a biztonságot a kombinációk rendkívüli száma adja.

Az ütközési esély a születésnap-paradoxon miatt gyorsabban nő, mint elsőre gondolnánk, mégis olyan sok lehetséges UUID marad, hogy jó minőségű generátorral elképesztően sok érték készíthető elfogadható kockázat mellett. A valódi veszély általában nem az elméleti valószínűség, hanem hibás random forrás, klónozott virtuális gép vagy saját, csonkolt formátum.

A generálás helye szabadon megválasztható

Automatikusan növekvő kulcsot jellemzően az adatbázis oszt ki a beszúráskor. UUID-t viszont létrehozhat a kliens, az API gateway, a doménszolgáltatás vagy az adatbázis is. Egy offline alkalmazás így azonnal stabil hivatkozást adhat egy új jegyzetnek, és a kapcsolódó képeket vagy módosításokat már a szinkronizáció előtt ehhez kötheti.

A korai azonosító az idempotenciát is támogatja. Ha a hálózat megszakad, a kliens ugyanazzal az ID-val ismételheti a létrehozási kérést. A szerver felismeri, hogy nem új objektumról van szó, így a bizonytalan válasz nem eredményez feltétlenül dupla rendelést vagy kétszer létrehozott feladatot.

A függetlenség egyszerűsíti az adatok egyesítését

Két adatbázisban egyaránt létezhet a 42-es felhasználó. Export vagy összeolvasztás közben minden idegen kulcsot át kell írni, ha a számtartományok ütköznek. Globálisan generált UUID-k esetén az objektumok és kapcsolataik többnyire eredeti azonosítóval vihetők át, ezért a migráció kevesebb koordinációt igényel.

Ez nem jelenti, hogy minden adat automatikusan összeegyeztethető. Két rendszer ugyanazt a valós személyt külön UUID-val ismerheti, vagy különböző jelentést adhat azonos mezőknek. A UUID a technikai kulcsütközést csökkenti; az entitásfeloldás és az üzleti deduplikáció továbbra is külön feladat.

A formátum szabványos, a szöveges alak mégis változhat

A leggyakoribb megjelenés öt hexadecimális csoport kötőjelekkel, például 8-4-4-4-12 karakteres felosztásban. Találkozhatunk nagybetűs írással, kapcsos zárójellel, kötőjel nélküli formával vagy urn:uuid: előtaggal is. Ezek bizonyos környezetben ugyanazt a 128 bites értéket jelölhetik.

A rendszernek kanonikus formát kell választania a kimenethez, miközben a bemenetnél tudatosan dönt az elfogadott változatokról. A normalizálás az összehasonlítás előtt történjen. Ha a stringet nyersen használjuk cache-kulcsként vagy aláírt üzenet részeként, két szöveges forma látszólag külön identitást hozhat létre.

A verzió megmondja, hogyan készült az érték

A UUID nem egyetlen generálási algoritmus neve. A verziómező jelzi, milyen összetevőkből állt elő. Egyes változatok időt, node-információt vagy nevet használnak, mások kriptográfiailag erős véletlen biteket, az újabb időrendezhető verziók pedig a modern adatbázisok igényeire is figyelnek.

A parsernek ezért nem elég azt ellenőriznie, hogy a string alakja hasonlít UUID-ra. Ha a protokoll kizárólag egy adott verziót enged, a verzió- és variánsbiteket is validálni kell. Egy tetszőleges hexadecimális sorozat formai egyezése nem bizonyítja, hogy szabványos generátor hozta létre.

A UUID nem titok és nem jogosultsági token

A nehezen kitalálható azonosító csökkentheti az egyszerű felsorolást, de nem helyettesíti az authorizationt. Ha valaki megszerez egy dokumentum UUID-ját logból, böngészőtörténetből vagy továbbított linkből, ettől még nem kellene hozzáférést kapnia. Minden kérésnél ellenőrizni kell a felhasználót, tenantot és műveleti jogot.

Megosztási vagy jelszó-visszaállítási linkhez külön, nagy entrópiájú capability token, lejárat és visszavonási lehetőség szükséges. Az erőforrás stabil UUID-ja túl hosszú életű és túl sok helyen jelenik meg ahhoz, hogy egyúttal hitelesítő adatként kezeljük.

A központi koordináció hiánya nem jelent ellenőrzés nélküli írást

Még jó generátor mellett is érdemes unique constraintet fenntartani az adatbázisban. Ez nem azért kell, mert rendszeres ütközésre számítunk, hanem mert az adatbázisnak kell megvédenie az identitási invariánst programhiba, rossz import vagy hibás tesztfixture esetén is.

Az ütközési hibát a szolgáltatás kezelheti újragenerálással, ha az ID valóban véletlen és még nem került külső félhez. Ha már publikus szerződés része, a csendes csere veszélyesebb. A monitoringnak azonnal láthatóvá kell tennie az ilyen eseményt, mert valószínűleg generátor- vagy adatfolyamhibát jelez.

A logokban az azonosító hasznos összekötő kapocs

Egy UUID végigkísérheti az objektumot API-n, queue-n és háttérfolyamaton keresztül. Segít összekapcsolni a szétszórt eseményeket anélkül, hogy személyes adatot írnánk minden logüzenetbe. Ettől még maga az azonosító is lehet érzékeny, ha publikus profilt vagy üzleti rekordot lehet vele feloldani.

A trace ID, request ID és doménobjektum ID ne mosódjon össze. Egy kérés több objektumot érinthet, ugyanaz az objektum pedig sok kérésben szerepelhet. A mezők külön elnevezése javítja a kereshetőséget és megakadályozza, hogy egy technikai korrelációs értékből tartós üzleti kulcs legyen.

Az elosztott létrehozás új munkafolyamatokat tesz lehetővé

Event-sourced rendszerben az esemény már az adatbázis-tranzakció előtt hivatkozhat az új aggregate-re. Több szolgáltatás előre lefoglalhat azonosítót közös sequence-szolgáltatás nélkül. Importfolyamat determinisztikusan hozzárendelheti a belső objektumot a feldolgozás teljes életciklusához.

A haszon nem pusztán teljesítmény. Kevesebb globális függőség azt jelenti, hogy egy központi ID-szolgáltatás kiesése nem állítja le az összes írást. Cserébe a csapatnak következetesen kell kezelnie a típust, a tárolást és a validációt minden résztvevő rendszerben.

A jó UUID-stratégia láthatatlan infrastruktúra

Ha a verzió illeszkedik a feladathoz, a generátor megbízható, az adatbázis helyesen tárolja és az API kanonikus formát használ, az azonosító ritkán kerül a figyelem középpontjába. Egyszerűen lehetővé teszi, hogy különálló komponensek ugyanarról az objektumról beszéljenek.

A UUID valódi értéke tehát nem a hosszú, technikainak tűnő string. Az a képesség, hogy az identitás létrehozása leválik egyetlen központi számlálóról. Ez rugalmasabb offline működést, biztonságosabb retry-t és könnyebb adategyesítést ad, miközben a rendszernek továbbra is világos szerződésekre és adatbázis-korlátokra van szüksége.