Asosiy kontentga o‘tish
Innovialabs

UUID yoki avtoinkrement: qaysi birlamchi kalitni tanlash kerak

Amaliyot4 daq

Qisqacha

Odatiy veb va mobil bekend uchun oqilona standart tanlov — nativ uuid turidagi UUIDv7: uni istalgan joyda yaratish mumkin, hajmlarni oshkor qilmaydi va deyarli avtoinkrement kabi qo‘shiladi; bitta bazadagi ichki jadvallar uchun bigint identity yaxshi.

Qisqa javob

  • bigint identity (avtoinkrement) — hammasi bitta bazada bo‘lsa va ID tashqariga ko‘rinmasa, eng ixcham va tez kalit.
  • UUIDv4 — hamma joyda noyob, lekin tasodifiy tartib katta jadvallarda indekslarga zarar qiladi.
  • UUIDv7 va ULID — hamma joyda noyob va vaqt bo‘yicha tartiblangan, shuning uchun deyarli avtoinkrement kabi qo‘shiladi.
  • Amaliy standart tanlov: API va URL’da ko‘rinadigan obyektlar uchun UUIDv7, loglar va bog‘lovchi jadvallar kabi ichki jadvallar uchun bigint.

Variantlar bitta jadvalda

TurHajmiQo‘shish tartibiURL’da taxmin qilinishiBazadan tashqarida yaratish
integer / bigint identity4 / 8 baytKetma-ketSaralab chiqish osonYo‘q
UUIDv416 baytTasodifiyTaxmin qilib bo‘lmaydiHa
UUIDv716 baytVaqt bo‘yichaTaxmin qilib bo‘lmaydi, lekin yaratilgan vaqt ko‘rinadiHa
ULID16 bayt (matnda 26 belgi)Vaqt bo‘yichaTaxmin qilib bo‘lmaydi, lekin yaratilgan vaqt ko‘rinadiHa

Indeks hajmi va qo‘shish tezligi

Hajm. UUID bigintning 8 baytiga qarshi 16 bayt egallaydi. Bu farq har bir indeks va jadvalga havola qiluvchi har bir tashqi kalitga ko‘payadi. UUID’ni satr sifatida emas, nativ turda saqlash kerak (PostgreSQL’da uuid, MySQL’da BINARY(16)): matnli variant ikki baravardan ko‘proq og‘ir va sekinroq solishtiriladi.

Qo‘shish. B-tree indeks yangi qiymatlar oxiriga kelishini yoqtiradi:

  • Avtoinkrement, UUIDv7 va ULID vaqt o‘tishi bilan o‘sadi — yangi yozuvlar indeksning «o‘ng chetiga» qo‘shiladi, faol sahifalar xotirada qoladi.
  • UUIDv4 tasodifiy — har bir qo‘shish indeksning ixtiyoriy joyiga tushadi. Katta jadvallarda bu sahifalarning ko‘proq bo‘linishi, diskdan ko‘proq o‘qish va keshning samarasizroq ishlashini anglatadi.

MySQL InnoDB’da ta’sir kuchliroq: u yerda birlamchi kalit klasterli, ya’ni jadvalning o‘zi kalit tartibida saqlanadi.

Xavfsizlik: URL’dagi taxmin qilinadigan ID’lar

Avtoinkrementda /orders/1042 manzili /orders/1041 ham mavjudligiga ishora qiladi. Bu ikki muammoga olib keladi:

  • Boshqalarning obyektlarini saralab chiqish. Agar serverda huquqlarni tekshirish unutilgan bo‘lsa, hujumchi shunchaki raqamni oshiradi. Muhim: bundan ID formati emas, avtorizatsiya tekshiruvi himoya qiladi. Tasodifiy ID hujumni qiyinlashtiradi, lekin tekshiruv o‘rnini bosmaydi.
  • Biznes ma’lumotlarining sizib chiqishi. Bir oy farq bilan olingan ikki ID orqali raqobatchi qancha buyurtma olayotganingizni baholaydi.

UUIDv7 va ULID’ning o‘z xususiyati bor: ularda yaratilgan vaqt kodlangan. Odatda bu zararsiz, lekin foydalanuvchi ro‘yxatdan o‘tgan payt maxfiy ma’lumot bo‘lsa, buni hisobga oling.

Bazalarni birlashtirish va taqsimlangan tizimlar

Avtoinkrement faqat bitta bazaning bitta jadvali ichida noyob. Muammolar quyidagi hollarda paydo bo‘ladi:

  • ikki bazadagi ma’lumotlarni birlashtirish kerak (ikki mintaqa, boshqa mahsulotni qo‘shib olish) — ID’lar to‘qnashadi;
  • mobil ilova oflayn ishlaydi va sinxronizatsiyadan oldin yozuvlar yaratadi — unga serverga murojaat qilmasdan darhol ID kerak;
  • servislar bog‘liq yozuvlarni parallel yaratadi va ID’larni oldindan bilishi kerak.

Har qanday UUID bularning barchasini hal qiladi: uni mijozda, servisda yoki bazada kelishuvsiz yaratish mumkin.

Qanday tanlash kerak

  • Bitta baza, ID’lar tashqariga chiqmaydi, ulkan jadvallar (hodisalar, loglar, bog‘lovchi jadvallar) — bigint generated always as identity.
  • Ochiq obyektlar: foydalanuvchilar, buyurtmalar, hujjatlar — UUIDv7.
  • Oflayn mijozlar va ID’ni qurilmada yaratish — UUIDv7 yoki ULID.
  • UUIDv4 — hatto yaratilgan vaqtni ham oshkor qilib bo‘lmasa va jadval tasodifiy qo‘shishlar muammo bo‘ladigan darajada katta bo‘lmasa.

Muqobil sxema — ikkita identifikator: JOIN va tashqi kalitlar uchun ichki bigint hamda API uchun noyob indeksli alohida ochiq UUID. Bu joyni tejaydi, lekin kodni murakkablashtiradi: qaysi ID qayerda ishlatilishini doim yodda tutish kerak.

CREATE TABLE orders (
  id uuid PRIMARY KEY,          -- UUIDv7, ilovada yoki bazada yaratiladi
  customer_id uuid NOT NULL REFERENCES customers (id),
  created_at timestamptz NOT NULL DEFAULT now()
);

UUIDv7’ni o‘rnatilgan yaratish hamma ma’lumotlar bazasi versiyalarida mavjud emas. Agar sizda bo‘lmasa, ilovada sinovdan o‘tgan kutubxonadan foydalaning.

Ko‘p uchraydigan xatolar

  • UUID’ni varchar(36)da saqlash.
  • O‘sib boradigan jadvallar uchun bigint o‘rniga integer ishlatish va bir necha yildan keyin chegaraga yetib qolish.
  • Tasodifiy ID’ni kirish huquqlarini tekshirish o‘rnini bosadi deb hisoblash.
  • UUIDv4 bo‘yicha saralab, xronologik tartibni kutish.

Ko‘p beriladigan savollar

Bo‘ladi, lekin bu tayyorgarlik talab qiladigan migratsiya: UUID ustunini qo‘shish, uni to‘ldirish, tashqi kalitlar va kodni yangilash, keyin birlamchi kalitni almashtirish. Ko‘pincha ichki bigintni qoldirib, faqat API uchun ochiq UUID qo‘shish osonroq.

Bunda yordam beramiz

O‘zingiz shug‘ullanmasdan natija olishni istasangiz — biz har kuni shu bilan shug‘ullanamiz.

Loyihani muhokama qilish

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.