Kimlik oluşturma
1) Neden tanımlayıcılara dikkat edin
Tanımlayıcı (ID) - varlığın temel anahtarı: veritabanı satırları, mesajlar, dosya, sipariş. Özellikleri bağlıdır:- Benzersizlik ve ölçek (çarpışmalar, yatay büyüme).
- Sıra ve sıralama (zaman korelasyonu, replikasyon, dedup).
- Depolama performansı (dizinler, sıcak sayfalar, anahtar boyutu).
- Güvenlik (öngörülemezlik, sızıntılar, tahmin).
- Kullanılabilirlik/entegrasyon (kısa, URL güvenli, büyük küçük harf duyarlı değil).
ID seçimi entropi, sipariş edilebilirlik, uzunluk, üretim hızı ve sömürü arasında bir uzlaşmadır.
2) Temel gereksinimler ve şartlar
Teklik: Çarpışma olasılığı kabul edilebilir riskten daha düşük olmalıdır.
Entropi:'ne kadar rastgelelik "ID (bit) içerir.
Time-sortable/k-sortable-Lexicographic ≈ zaman tabanlı sıralama.
Monotonluk: Bir düğüm/akış içinde azalmayan bir dizi.
Giriş yeri: yeni ekin dizinin "kuyruğunda'ne kadar yoğunlaştığı (sıcak sayfaların tehlikesi).
Öngörülebilirlik: Komşu kimlikleri tahmin etmek mümkün müdür (güvenlik/API için önemlidir).
Gösterim: binary/string, Base16/32/36/58/64, tire, case.
3) Büyük tanımlayıcı aileler
3. 1 UUID
V4 (rastgele): 122 bit entropi. Düzensiz, güvenlik ve basitlik için iyi. Eksi: rastgele dağılım nedeniyle "kaotik" endeksler - bununla birlikte, yükleri eşit olarak dağıtır ve "sıcak sayfaları" kaldırır.
v1 (zaman + MAC): düzenlemek, ancak MAC/zaman (gizlilik) taşır; çoğu zaman kaçınılır.
V7 (zaman sıralı): milisaniye süresi + rastgele bölüm. zamana göre sözlüksel sıralama ve veritabanında iyi sıkıştırma için tasarım. Uzlaşma: Endeksin "sıcak kuyruğu" görünür; shardening/prefixes/increment ile işlenir.
İpuçları
Harici API'ler ve gevşek sipariş gereksinimleri için - v4.
Olay/log veritabanları ve "sıralı" anahtarlar için - v7.
3. 2 ULID (Crockford Base32)
128 bit: 48 bit zaman (ms) + 80 bit rastgelelik. Lexicographically zamana göre sıralanmış, insan dostu ('I, L, O, U' olmadan), URL güvenli. Monoton bir varyasyon vardır (aynı zaman damgasıyla, rastgele kısım artar).
Artıları: okunabilirlik, düzenlenebilirlik, taşınabilirlik.
Eksileri: zaman içinde bir noktada çok yüksek bir ekleme sıklığı ile - "sıcak kuyruk".
3. 3 KSUID
160 bit: Döneme göre 32 bit zaman (sn) + 128 bit rastgelelik. Daha geniş zaman aralığı ve kararlı sıralama, ULID'den daha kısa dizeler? (Artık değil, kendi kodlamasıyla), dağıtılmış günlükler ve nesneler için iyidir.
3. 4 Kar tanesi benzeri (k-sortable flake IDs)
Klasik şema (özel):
[ timestamp bits ][ region/datacenter bits ][ worker bits ][ sequence bits ]
Özellikler: Bir düğümde monoton büyüme, yarı küresel benzersizlik, kısa (64 bit) ikili gösterim.
Riskler: Saat bağımlılığı (zaman kayması/regresyon), bir kenede sıranın tükenmesi, bölge/işçi bitlerinin koordinasyonu.
Tedavi: "geri saat", rezerv dizisi, zaman dedektörü, PTP/NTP disipline karşı koruma.
3. 5 DB dizisi (SEQUENCE/IDENTITY)
Bir DBMS/parça içinde en basit monoton nesil.
Artıları: kısa, hızlı, yerel tablolar için uygun.
Eksileri: dağıtılmış bir kümede küresel olarak zor; Öngörülebilir (açık anahtar olarak güvensiz), indeksin sıcak kuyruğunu oluşturur.
3. 6 İçerik adresi kimlikleri (hash içeriği)
İçerik SHA-256/Blake3 - kararlı kimlik, veri tekilleştirme, bütünlük denetimi, önbelleğe alma.
Artıları: determinizm, ikame karşı koruma.
Eksileri: pahalı üretim (CPU), çarpışmalar pratik sıfırlar, zaman sıralaması yok, uzunluk.
4) Çarpışmalar ve "doğum günü paradoksu" (sezgisel)
'n 'nesilde'b' bitlerinin rastgele bir kimliği için çarpışma olasılığı yaklaşık olarak:
p ≈ 1 - exp (-n (n-1 )/2/2 ^ b) ≈ n ^ 2/2 ^ (b + 1) (for small p)
Örnekler:
- UUIDv4 (122 bit) n = 10 ^ 12 (trilyon) - p ~ 1e-14 (ihmal edilebilir).
- 64-bit rasgele - n = 10 ^ 9 zaten p ~ 0 ile. 027 (dikkate değer risk).
- Sonuç: 64-bit rasgele genellikle büyük sistemler için yeterli değildir; 96/128 bit kullanın.
5) Dizinler, sıcak sayfalar ve depolama
Rastgele anahtarlar (v4) ekleri dizin ağacı boyunca eşit olarak dağıtır - "kuyruk" yoktur, ancak önbellek yeri daha kötüdür.
Zamana göre sıralanmış (v7/ULID/Snowflake) "kuyruğa" eklenir - daha iyi yerellik ve sıkıştırma, ancak yüksek paralel kayıt altında sıcak sayfaların riski.
- Kiracı/bölgeye göre ön ekler/sharding (zamandan önce 1-2 bayt ekleyin);
- interleaving: yüksek bitlerdeki rastgeleliğin bir parçası;
- Toplu ekler, B ağacında dolgu maddesi, büyük günlükler için BRIN/kümelemeye otomatik geçiş.
- 'UUID (16B)' vs 'BIGINT (8B)'/' INT8' bellek/önbellek sağlar; Base32/58/64 satırlar boyutu %20-60 artırır. Veritabanı için ikili depolayın, kenardaki bir dizeye serileştirin.
6) Güvenlik ve gizlilik
URL/API'de halka açık kimlikler olarak SEQUENCE/INT kullanmayın: tahmin edilebilir - kaynakların numaralandırılması.
Harici referanslar için rastgele, öngörülemeyen kimlikler (v4/v7/ULID/KSUID) ekleyin.
PII'yi ID'ye kodlamayın. Özniteliği etkinleştirmek istiyorsanız, şifreleyin/imzalayın (örneğin, JWE/JWS) veya opak belirteçler kullanın.
URL güvenli kodlamalar: Base32 Crockford, Base58 ('0OIl' olmadan), Base64url.
7) Çok kiracılık, önekler ve yönlendirme
Biçim: '[TENANT _ PREFIX] - [ID]' veya ikili: 'tenant _ id | | id'.
Artıları: hızlı filtreler/kiracı partileri, N + 1 taramalarına karşı koruma.
Eksileri: Daha yüksek bitlerdeki entropi yoğunluğunu kötüleştirebilir - dağılımı göz önünde bulundurun (ön ek hash).
Özet eki (2-3 bayt) çakışmaları azaltır ve parça yönlendirmesine yardımcı olur: 'shard = hash (id) % N'.
8) Seçim için pratik öneriler
API, genel bağlantılar, katı düzen olmadan dağıtılmış hizmetler: UUIDv4, ULID/KSUID.
Genellikle zamana göre sıraladığımız günlükler/olaylar/siparişler: UUIDv7 veya ULID (monoton).
Yerel monotonluk ve kısa anahtarla ultra yüksek bant genişliği: Kar tanesi benzeri 64 bit (zaman disiplini gerekli).
Artifaktların/yapıların/blobların tonozları: içerik adreslenebilir (SHA-256) ve üstte - insan dostu kısa bir "vitrin" (Hashids/link).
Bir veritabanındaki yerel tablolar: Halka açık bağlantılar için SEQUENCE/IDENTITY + harici "sarıcı" (maskeleme).
9) Uygulamalar ve örnekler
9. 1 PostgreSQL
UUID ikili dosyasını, indekslerini - gerektiğinde 'btree' veya 'hash' depolayın.
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);
Sıralı sıcak düzeltme: zaman sıralı kimlik için, üst bitlere "tuz" ekleyin veya kiracıya göre puan verin:
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 (atom sayaçları/monutonia)
bash
INCR "seq: orders" # local sequence combine: epoch_ms<<20 (worker_id<<10) (seq & 1023)
9. 3 Kar tanesi benzeri jeneratör (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. Uygulamalarda 4 ULID/UUID
Git
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())
Düğüm. 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) Kodlamalar ve temsiller
Veritabanında ikili ('BYTEA', 'UUID') - kompakt ve hızlı. Kenarda, şuna dönüştürün:- Base32 Crockford (ULID): durum duyarsız, görsel olarak benzer karakterler yok.
- Base58: kısaca Base32/64 insan tarafından okunabilir belirteçler için, URL güvenli.
- Base64url: kısa, ama URL'de '-'ve' _ '.
Dizeleri karşılaştırırken yinelemeleri önlemek için durum ve biçimi (tireler/yok) dengeleyin.
11) Oyun kitaplarını ve gözlemlenebilirliği test edin
Çarpışmalar: metrik'id _ collision _ total '(0 olmalı),> 0'da uyarı.
Önek dağılımı: yüksek baytların histogramı - satın almak istiyoruz.
Üretim hızı: 'ids _ per _ sec', p99 jeneratör gecikmesi.
Saat eğriliği (Snowflake için): ofset düğümleri, "saat geri gitti" olayları.
Dizin kuyrukları: p95/p99 'INSERT' gecikme; Kilitlerin/sıcak sayfaların oranı.
- Enjeksiyon "saat kayması/geri" - jeneratörün beklediğinden/değiştiğinden emin olun.
- Milisaniye cinsinden 'eşitlik' taşması - next_ms bekleme kontrolü.
- Kütle paralelliği - dizinde kilitlerin fırtınaları olup olmadığı.
12) Anti-desenler
AUTO_INCREMENT/SEQUENCE bir kamu kimliği olarak: tahmin, sızıntılar. Dahili kimlik yerine genel opak kimlik kullan.
UUIDv1 (MAC/time) çıkışı: gizlilik.
Trilyon giriş başına 64 bit rastgele kimlik: gerçek çarpışma riski.
HA: SPOF ve darboğaz olmadan küresel "merkezi jeneratör".
Saat geri koruması olmadan zaman sıralı kimlikler: kopyalar/sipariş regresyonu.
Açık bir sürüm/önek olmadan farklı kimlik formatlarının karıştırılması - tartışma/geçişlerde kaos.
ID'yi farklı kayıt/formlara sahip bir dize olarak kaydetme - gizli kopyalar.
13) Uygulama kontrol listesi
- Etki alanı gereksinimleri için seçilmiş biçim (v4/v7/ULID/KSUID/Snowflake/SEQ/hash).
- Sipariş gereksinimleri tanımlanmıştır (sıralanabilirliğin gerekli olup olmadığı).
- Çarpışma olasılığı (b bit, n nesil) tahmin edilir ve risk eşiği belirlenir.
- Kodlama tasarlanmıştır (DB + insan tarafından okunabilir vitrinde ikili).
- Zaman sıralı için - saat geri koruması, dizi sınırları ve NTP/PTP disiplini.
- Kamu kimlikleri için - öngörülemezlik (rastgele/ULID/KSUID), PII yokluğu.
- Karma (id) % N, çok kiracılı önekler düşünülmüş.
- Gözlemlenebilirlik: çarpışma, dağılım, gecikme, saat eğriltme metrikleri.
- Sıra/Çekişme/Pencere Uzunluğu Taşma Testi Örnekleri.
- Biçim, sürüm, dönem, bitmap ve geçiş planı belgeleri.
14) SSS
S: Mikro hizmetler için "varsayılan'ne seçilir?
C: UUIDv7 veya ULID: zaman düzeni, çok fazla entropi, sınırda basit üretim. Harici API'ler için, ULID/UUIDv4 da yakl.
S: Kısa ve insan tarafından okunabilir bir kimliğe ihtiyacınız var.
A: ULID/KSUID veya Base58-128-bit rastgele/geçici kimlik kodlaması. Uzunluk ve çarpışmaları hatırlayın.
S: "Kısa sayısal" kimlikler yapmak mümkün mü, ancak güvenli mi?
C: Evet: dahili SEQ'yi saklayın ve dışarıda opak belirteci (rastgele 96-128 bit) veya tuz + imzalı Hashids verin.
S: SEQ'den UUIDv7'ye nasıl geçebilirim?
C: Yeni bir'id _ new '(UUID) sütunu girin, iki parçalı, yeni kimliğe referanslar yayınlayın, ardından DC/yabancı anahtarları değiştirin ve eskisini silin.
S: ULID eklerim neden "sıcak'oldu?
C: Kesinlikle artan tuşları bir dizine ekleyin. Bölüm/kiracı, yüksek sipariş bitlerini karıştırın, toplu ekler kullanın.
15) Toplam
İyi bir kimlik, sorun için doğru özellik kümesidir: yeterli entropi, öngörülebilir sıralama (gerekirse), güvenli tanıtım ve endekslerin sağlıklı kullanımı. Basitlik ve dağıtım için UUIDv4/ULID/UUIDv7/KSUID, yoğun monotonluk ve kısa anahtarlar (zaman disiplini için), yerel tablolar için diziler, eserler için içerik karmaları için Snowflake'i seçin. Gözlemlenebilirliği ve testleri ortaya koyun - ve tanımlayıcılar bir sürpriz kaynağı olmaktan çıkacaktır.