UUID v4 vs v7: kurį unikalų identifikatorių pasirinkti?

UUID yra 128 bitų identifikatorius, unikalus be centrinio koordinavimo. Versija 4, visiškai atsitiktinė, dominuoja jau metų metus. Versija 7, naujesnė (RFC 9562, 2024), priekyje integruoja laiko žymą, kad sukurtų laike surikiuotus identifikatorius. Šis skirtumas, iš pažiūros nereikšmingas, radikaliai keičia našumą duomenų bazėje. Štai kurį rinktis.

Kas yra UUID?

UUID (Universally Unique Identifier) yra 128 bitų skaičius, vaizduojamas 32 šešioliktainiais simboliais, sugrupuotais į penkis blokus, pavyzdžiui 550e8400-e29b-41d4-a716-446655440000. Jo paskirtis: sugeneruoti unikalų identifikatorių neprašant centrinės institucijos, todėl jis idealus paskirstytoms sistemoms. Galite jų sugeneruoti su mūsų UUID generatoriumi.

Yra kelios versijos; aktualiausios šiandien įrašų raktams yra v4 (atsitiktinė) ir v7 (surikiuota laike).

UUID v4 (atsitiktinis)

UUID v4 sudaro 122 atsitiktiniai bitai (likę koduoja versiją ir variantą). Susidūrimo tikimybė tokia maža, kad praktikoje nereikšminga. Tai numatytoji versija daugumoje kalbų ir bibliotekų.

  • Nenuspėjamas: tobulas žetonams ar viešiems identifikatoriams, kurių nenorima atspėjamų
  • Jokio informacijos nutekėjimo: neatskleidžia nei datos, nei sukūrimo eilės
  • Trūkumas: visiškai netvarkingas, o tai kankina duomenų bazės indeksus

UUID v7 (surikiuotas laike)

UUID v7 pirmuose 48 bituose įdeda Unix laiko žymą milisekundėmis, po kurios eina atsitiktiniai bitai. Du UUID v7, sugeneruoti skirtingais momentais, taigi rikiuojasi pagal jų sukūrimo tvarką, išliekant unikalūs ir praktiškai neįmanomi atspėti.

  • Rikiuojamas: leksikografinė tvarka atitinka chronologinę tvarką
  • Draugiškas indeksams: įterpimai vyksta indekso pabaigoje, kaip automatinis didinimas
  • Atsvara: jis atskleidžia sukūrimo momentą, o tai gali būti nepageidaujama viešam identifikatoriui

Palyginimo lentelė

Kriterijus UUID v4 UUID v7
Sudėtis122 atsitiktiniai bitaiLaiko žyma + atsitiktinis
Surikiuotas laikeNeTaip
RikiuojamasNeTaip (chronologiškai)
Indekso našumasMažas (fragmentacija)Didelis (nuoseklūs įterpimai)
NenuspėjamumasVisiškasDidelis, bet atskleidžia momentą
Informacijos nutekėjimasJoksSukūrimo data
Branda / palaikymasUniversalusNaujas (RFC 9562, 2024)

Poveikis duomenų bazėms

Tai temos esmė. Reliacinės duomenų bazės saugo savo indeksus B medžiuose (B-tree). Įterpiant atsitiktinius raktus (v4), rašymai išsklaidomi visur indekse, sukeliant fragmentaciją, puslapių skilimą ir mažiau efektyvią talpyklą. Dideliems kiekiams įterpimo našumas pastebimai degraduoja.

Surikiuoti raktai (v7) visada įterpiami indekso pabaigoje, kaip automatiškai didinamas identifikatorius. Gaunami greiti įterpimai, geresnis lokalumas ir kompaktiškesnis indeksas. Tai ypač akivaizdu su pirminiu raktu InnoDB (MySQL), kur pirminis raktas nustato fizinę eilučių tvarką.

Kada rinktis vieną ar kitą

Rinktis UUID v4, kai

  • Identifikatorius yra viešai matomas ir neturi nieko atskleisti
  • Generuojate žetonus, dalijimosi nuorodas, paslaptis
  • Eilė ir sukūrimo data neturi būti atspėjamos
  • Norite maksimalaus suderinamumo su esama sistema

Rinktis UUID v7, kai

  • UUID naudojamas kaip pirminis raktas duomenų bazėje
  • Įterpimų kiekis yra didelis ir indekso našumas svarbus
  • Norite rikiuoti pagal sukūrimo tvarką be specialaus stulpelio
  • Sukūrimo momento atskleidimas nėra problema

Rekomendacija

Duomenų bazės pirminiam raktui dabar rinkitės UUID v7: išlaikote paskirstytą UUID unikalumą, kartu išvengdami v4 indekso baudos. Palikite UUID v4 viešiems identifikatoriams, žetonams ir paslaptims, kur svarbiausia visiškas nenuspėjamumas ir laiko nutekėjimo nebuvimas.

Vis dėlto patikrinkite v7 palaikymą savo kalboje ir ORM: RFC yra naujas, bet plitimas sparčiai progresuoja.

Dažnai užduodami klausimai

Ar UUID v7 mažiau saugus nei v4?

Jį vis dar labai sunku atspėti dėl atsitiktinių bitų, bet jis atskleidžia sukūrimo momentą per savo laiko žymą. Viešam identifikatoriui, kur data neturi nutekėti, ar paslapčiai rinkitės v4.

Kodėl UUID v4 lėtina duomenų bazes?

Nes jo atsitiktinės reikšmės išsklaido įterpimus po visą B-tree indeksą, o tai fragmentuoja puslapius ir mažina talpyklos efektyvumą. Surikiuota v7 įterpia indekso pabaigoje ir išvengia šios problemos.

Ar galiu migruoti iš v4 į v7?

Taip naujiems įrašams: abu formatai sugyvena tame pačiame UUID stulpelyje. Nereikia perrašyti istorijos; tiesiog perjunkite naujų raktų generavimą į v7.

O kaip dėl v1 ir v6 versijų?

v1 koduoja laiko žymą ir MAC adresą, o tai kelia konfidencialumo problemų. v6 perrikiuoja v1, kad ją būtų galima rikiuoti. Naujam projektui v7 yra RFC 9562 rekomenduojama surikiuota versija.