GH GambleHub

Generazione di ID

1) Perché prestare attenzione agli identificatori

ID è la chiave fondamentale dell'entità: righe di database, messaggi, file, ordine. Le sue proprietà dipendono da:
  • Unicità e scala (collisioni, crescita orizzontale).
  • Ordine e ordinamento (correlazione temporanea, replica, deduzione).
  • Prestazioni di storage (indici, pagine hot, dimensioni della chiave).
  • Sicurezza (imprevedibilità, fughe, indovinazione).
  • Yusability/integrazione (breve, URL-safe, non sensibile al maiuscolo).

La scelta dell'ID è un compromesso tra entropia, ordinabilità, lunghezza, velocità di generazione e funzionamento.

2) Requisiti e termini chiave

L'unicità è che le probabilità di collisione devono essere inferiori al rischio accettabile.
Entropia: «quante casualità» contiene un ID (bit).
Ordinabilità (time-sortable/k-sortable) - Ordinamento lessicografico per ora.
Monotonia: sequenza non decrescente all'interno del nodo/flusso.
Locale di scrittura - Quanto il nuovo inserimento è concentrato nella coda dell'indice (pericolo delle pagine calde).
Prevedibile: è possibile indovinare l'ID adiacente (importante per la protezione/API).
Rappresentazione binaria/stringa, Base16/32/ 36/58/64, trattini, maiuscole.

3) Famiglie di identificatori di base

3. 1 UUID

v4 (random): 122 bit di entropia. Disordinamento, buono per la sicurezza e la semplicità. Meno: «caotica» gli indici a causa della distribuzione accidentale - che, tuttavia, disperde uniformemente i carichi e elimina le pagine calde.
v1 (time + MAC) - Organizziamo, ma porta MAS/tempo (privacy); Spesso evitano.
v7 (time-ordered) - Tempo di millisecondi + parte random. Progettato per ordinamento lessicografico in base al tempo e buona compressione nel database. Compromesso: viene visualizzata la coda calda dell'indice; curato con charding/prefissi/incremento.

Suggerimenti

Per API esterne e requisiti di ordine non validi - v4.
Per i database di eventi/tana e le chiavi «ordinate», v7.

3. 2 ULID (Crockford Base32)

128 bit: 48 bit di tempo (mc) + 80 bit di casualità. Lessicograficamente ordinato per tempo, uomo-amichevole (senza «I, L, O, U»), URL-safe. C'è una variazione monotona (con la stessa etichetta di tempo, la parte casuale aumenta).
I vantaggi sono leggibilità, ordinabilità, portabilità.
Contro: con una frequenza di inserimento molto elevata in un momento, la coda calda.

3. 3 KSUID

160 bit: 32 bit di tempo (secondi) rispetto all'era + 128 bit di casualità. Più intervallo temporale e più ordinabile, righe più brevi di ULID? (no - più lungo, ma con la sua codifica), è buono per i fogli e gli oggetti distribuiti.

3. 4 Snowflake simili (k-sortable flake IDs)

Schema classico (personalizzabile):

[ timestamp bits ][ region/datacenter bits ][ worker bits ][ sequence bits ]

Proprietà: crescita monotona sul nodo, unicità quasi-globale, rappresentazione binaria breve (64 bit).
Rischi: dipendenza da orologi (deriva/regressione temporale), esaurimento sequence in una singola teca, coordinazione di bit region/worker.
Si tratta di protezione da clock back, sequence, rilevatore del tempo, disciplina PTP/NTP.

3. 5 Sequenze di database (SEQUENCE/IDENTITY)

Una semplice generazione monotona in un DB/shard.
I vantaggi sono brevi, veloci, confortevoli per le tabelle locali.
Contro: difficile da raggiungere globalmente in un cluster distribuito prevedibilmente (non sicuro come chiave pubblica), crea una coda calda dell'indice.

3. 6 ID indirizzi contenuti (hash content)

SHA-256/Blake3 dal contenuto → l'ID stabile, la deduplicazione, la verifica dell'integrità, la cache.
I vantaggi sono il determinismo, la protezione contro il cambio.
Contro: generazione costosa (CPU), collusioni di zeri pratici, nessun ordine temporale, lunghezza.

4) Collisioni e «paradosso di compleanno» (intuitivo)

La probabilità di collisione per l'ID casuale della dimensione «b» bit a «n» generazioni è approssimativa:

p ≈ 1 - exp (-n (n-1 )/2/2 ^ b) ≈ n ^ 2/2 ^ (b + 1) (for small p)
Esempi:
  • UIDv4 (122 bit) a n = 10 ^ 12 (trilione) → p = 1e-14 (trascurabile).
  • 64 bit rand a n = 10 ^ 9 è già p} 0. 027 (rischio notevole).
  • Conclusione: 64 bit casuali sono spesso pochi per sistemi enormi; utilizzare 96/128 bit.

5) Indici, pagine calde e memorizzazione

Le chiavi casuali (v4) distribuiscono gli inserti in modo uniforme nella struttura Indice non c'è una coda, ma una posizione cache peggiore.
I tempi ordinati (v7/ULID/Snowflake) vengono inseriti in coda per la posizione e la compressione migliori, ma il rischio di pagine calde sotto un record parallelo elevato.

Allentamento della coda calda:
  • prefissi/charding per tenant/region (aggiungi 1-2 byte prima dell'ora);
  • interleaving: parte di casualità in mazza senior;
  • inserimento di batch, filfactor nell'albero B, correzione automatica su BRIN/clustering per grandi logi.
La dimensione è importante:
  • 'UUID (16B) 'vs'BIGINT (8B) '/' INT8' risparmia memoria/cache; le righe Base32/58/64 aumentano le dimensioni del 20-60%. Per il database, conservare binario, serializzare in una riga sul bordo.

6) Sicurezza e privacy

Non usare SEQUENCE/INT come ID pubblici nell'URL/API: è possibile indovinare l'elenco delle risorse.
Aggiungi un ID random e imprevedibile (v4/v7/ULID/KSUID) per i collegamenti esterni.
Non codificare il PII nell'ID. Se si desidera attivare un attributo, cifrare/firmare (ad esempio JWE/JWS) o utilizzare token opachi.
Codifiche protette URL: Base32 Crockford, Base58 (senza «0OIl»), Base64url.

7) Multi-tenenza, prefissi e routing

Formato: '[TENANT _ PREFIX] - [ID]' o binario: 'tenant _ id | id'.
I vantaggi sono filtri/partiture veloci per locatore, protezione da N + 1 scene.
Contro: può peggiorare la densità di entropia nei bit senior, quindi pensare alla distribuzione (hash prefisso).
Il suffisso hash (2-3 byte) riduce i conflitti e aiuta il routing shard: 'shard = hash (id)% N'.

8) Suggerimenti pratici per la scelta

API, collegamenti pubblici, servizi distribuiti senza rigidità: UUIDv4, ULID/KSUID.
Logi/eventi/ordini, dove spesso ordiniamo in base al tempo: UUIDv7 o ULID (monotono).
Banda ultra larga con monotonia locale e chiave corta: Snowflake-simile a 64 bit (richiede una disciplina del tempo).
Magazzini di manufatti/cartelle/blob: indirizzi contenuti (SHA-256), mentre sopra c'è una vetrina breve-amichevole umana (Hasids/link).
Tabelle locali in un database: SEQUENCE/IDENTITY + avvolgimento esterno per riferimenti pubblici (masking).

9) Implementazioni e esempi

9. 1 PostgreSQL

Conserva l'UUID binario, gli indici sono btree o hash per necessità.

sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE orders (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(), -- или uuid_generate_v4()
created_at timestamptz NOT NULL DEFAULT now(),
tenant smallint NOT NULL
);

-- For time-sortable (UUIDv7) store binary (uuid), generation in the application.
-- If you want a cluster by time:
CREATE INDEX ON orders (created_at DESC);
Sequential hot fix - Per time-sorted ID, aggiungi «sale» ai bit senior o partigiani per tenant:
sql
CREATE TABLE orders_t1 PARTITION OF orders FOR VALUES IN (1);
CREATE TABLE orders_t2 PARTITION OF orders FOR VALUES IN (2);

9. 2 Redis (contatori atomici/monotonia)

bash
INCR "seq: orders" # local sequence combine: epoch_ms<<20     (worker_id<<10)      (seq & 1023)

9. 3 Generatore snowflake simile (pseudocode)

pseudo const EPOCH =  1704067200000  # custom epoch (ms)
state: last_ms=0, seq=0, worker=7, region=3

next():
now = epoch_ms()
if now < last_ms: wait_until(last_ms)    # защита от clock back if now == last_ms:
seq = (seq + 1) & ((1<<12)-1)      # 12 бит if seq == 0: wait_next_ms()
else:
seq = 0 last_ms = now return (now-EPOCH)<<22      region<<17      worker<<12      seq

9. 4 ULID/UUID nelle applicazioni

Go

go
// ULID t:= time. Now(). UTC()
entropy:= ulid. Monotonic(rand. New(rand. NewSource(t. UnixNano())), 0)
id:= ulid. MustNew(ulid. Timestamp(t), entropy)

//UUID v7 (if there is a library)
id:= uuid. Must(uuid. NewV7())

Node. js

js import { ulid } from 'ulid';
import { v4 as uuidv4 } from 'uuid';
const id1 = ulid();
const id2 = uuidv4(); // v4

Python

python import uuid, time id_v4 = uuid. uuid4()
For v7, use a library (for example, uuid6/7 third-party packages)

10) Codifiche e visualizzazioni

Binario nel database («BYTEA», «UUID») è compatto e veloce. Sul bordo, convertire in:
  • Base32 Crockford (ULID) - È insensibile al maiuscolo, senza caratteri visivi simili.
  • Base58: più breve di Base32/64 per token umani, URL-safe.
  • Base64url: breve, ma - e '_' nell'URL.

Stabilizzare la minuscola e il formato (difetti/assenza) per evitare duplicati quando si confrontano le righe.

11) Test playbook e osservazione

Collisioni: metrica 'id _ collision _ total' (deve essere 0), alert a> 0.
Distribuzione dei prefissi: istogramma dei byte senior - Cerca compravendite.
Velocità di generazione: 'ids _ per _ sec', p99 latitanza generatore.
Clock skew (per Snowflake) - Offset nodi, eventi «clock went back».
Code indice: p95/p99 'INSERT'latency; la quota di blocchi/pagine calde.

Game day:
  • L'iniezione «clock draft/back» si assicura che il generatore sia in attesa o in transizione.
  • Sequence in millisecondi esegue il controllo di attesa next _ ms.
  • Il parallelismo di massa dice se le tempeste sono bloccate nell'indice.

12) Anti-pattern

AUTO _ INCREMENT/SEQUENCE come ID pubblico - Indovina, fuoriuscita. Utilizzare un ID opaco pubblico sopra quello interno.
UIDv1 (AS/tempo) verso l'esterno: privacy.
64 bit ID casuale per trilioni di record, il rischio reale di conflitti.
Generatore centrale globale senza SPOF, SPOF e ristretto.
Time-sorted IDs senza protezione da clock back - Duplicati/regresso ordine.
La miscelazione di diversi formati di ID senza una versione/prefisso esplicito ha creato un caos in debag/migrazioni.
Salva l'ID come righe con minuscole o forme diverse e duplicati nascosti.

13) Assegno-foglio di implementazione

  • È selezionato un formato (v4/v7/ULID/KSUID/Snowflake/SEQ/hash) per i requisiti di dominio.
  • Sono stati definiti i requisiti di ordinamento (se necessario).
  • È stata valutata la probabilità di collisioni (b bit, n generazioni) e viene specificata una soglia di rischio.
  • Codifica progettata (binariamente in database + vetrina umana).
  • Time-sorted - Protezione da clock back, sequence-limite e NTP/PTP disciplina.
  • Per un ID pubblico è imprevedibile (rand/ULID/KSUID), nessun PII.
  • Raggruppamento shard (hash (id)% N), prefissi multi-tenanti.
  • Osservabilità: metriche di conflitti, distribuzione, ritardi, clock skew.
  • Valigette di prova per il sovraccarico sequence/alta concorrenza/lunghezza della finestra.
  • Documentazione del formato, della versione, dell'epoca, del bit e del piano di migrazione.

14) FAQ

Q: Che scelta è predefinita per i microservizi?
A: UUIDv7 o ULID: regolabilità del tempo, molta entropia, semplice generazione sul bordo. Anche per le API esterne - ULID/UUIDv4.

Q: È necessario un ID breve e umano.
A: ULID/KSUID o Base58-codifica di 128 bit ID casuale/temporaneo. Ricordate la lunghezza e le collusioni.

Q: È possibile creare un ID numerico «breve», ma sicuro?
A: Sì: Conserva il SEQ interno, e porta fuori opache token (rand 96-128 bit) o Hasids con sale + firma.

Q: Come migrare da SEQ a UUIDv7?
A: Inserisci la nuova colonna «id _ new» (UUID), abbina, pubblica i riferimenti al nuovo ID, quindi fai clic su CAD/chiavi esterne e rimuovi la vecchia.

Perché le mie inserzioni con ULID sono diventate «hot»?
A: Inserisci chiavi rigorosamente crescenti nello stesso indice. Frammentare i lotti/tenant, mescolare i botti senior, utilizzare le inserzioni batch.

15) Riepilogo

Un buon ID è il giusto insieme di proprietà per l'attività: entropia sufficiente, ordinamento prevedibile (se necessario), pubblicità sicura e utilizzo sano degli indici. Scegli UIDv4/ULID/UUIDv7/KSUID per la semplicità e la distribuzione, Snowflake per la monotonia e le chiavi brevi (a tempo determinato), sequenza per le tabelle locali, hash per i contenuti per gli artefatti. Fissare l'osservabilità, i test e gli identificatori non saranno più una fonte di sorprese.

Contact

Mettiti in contatto

Scrivici per qualsiasi domanda o richiesta di supporto.Siamo sempre pronti ad aiutarti!

Telegram
@Gamble_GC
Avvia integrazione

L’Email è obbligatoria. Telegram o WhatsApp — opzionali.

Il tuo nome opzionale
Email opzionale
Oggetto opzionale
Messaggio opzionale
Telegram opzionale
@
Se indichi Telegram — ti risponderemo anche lì, oltre che via Email.
WhatsApp opzionale
Formato: +prefisso internazionale e numero (ad es. +39XXXXXXXXX).

Cliccando sul pulsante, acconsenti al trattamento dei dati.