Bosh sahifa Wiki Upsert

Upsert

Upsert — berilgan kalitga mos yozuv mavjud bo‘lmasa uni yaratish, mavjud bo‘lsa yangilashni bitta ma’lumotlar bazasi amali sifatida bajarish usuli. Atama update va insert so‘zlaridan tuzilgan. Upsert alohida “avval qidir, keyin insert yoki update qil” ketma-ketligidan farqli ravishda parallel so‘rovlar orasidagi poyga holatini baza darajasida boshqarishi mumkin.

Kalit va konflikt

Qaysi yozuv yangilanishi primary key yoki unique constraint bilan aniqlanadi. Masalan, foydalanuvchining elektron pochta manzili unique bo‘lsa, yangi qiymat shu constraint bilan konflikt qilganda mavjud qator yangilanishi mumkin. Konflikt nishoni noto‘g‘ri tanlansa, boshqa mantiqiy obyekt ustiga yozish yoki kutilmagan dublikat paydo bo‘lishi ehtimol.

PostgreSQL sintaksisida bu INSERT ... ON CONFLICT orqali ifodalanadi:

INSERT INTO counters (name, value)
VALUES ('downloads', 1)
ON CONFLICT (name)
DO UPDATE SET value = counters.value + 1;

Bu misol name bo‘yicha yozuv bo‘lmasa yaratadi, bo‘lsa hisoblagichni oshiradi. EXCLUDED psevdoyozuvi kiritishga urinishdagi yangi qiymatlarni olish uchun ishlatiladi. MySQL oilasida INSERT ... ON DUPLICATE KEY UPDATE, SQL standartida va ayrim bazalarda MERGE shunga yaqin vazifani bajaradi, lekin ularning concurrency va trigger semantikasi aynan bir xil emas.

Atomiklik va parallel bajarilish

Ilova avval SELECT qilib, keyin qaror chiqarsa, ikki tranzaksiya bir vaqtda yozuv yo‘q deb ko‘rishi mumkin. Ikkalasi insert qilganda biri unique constraint xatosi oladi. Upsert konfliktni indeks va tranzaksiya mexanizmi ichida hal qiladi. Shunga qaramay, u barcha poyga holatini yo‘q qilmaydi: update ifodasi eski qiymatni qanday o‘qishi va isolation level natijaga ta’sir qiladi.

“Qiymatni 1 ga oshirish” bilan “qiymatni 1 ga o‘rnatish” turli semantikadir. Birinchi amal takroriy so‘rovda yana oshadi va idempotent emas. Ikkinchisi bir xil maqsad holatini qayta o‘rnatadi. Upsertning mavjudligi operatsiyani avtomatik idempotent qilmaydi.

Ma’lumotlar birlashtirilishi

Upsert konfiguratsiya sinxronlash, tashqi katalog importi, materialized holat va hisoblagichlarda ishlatiladi. Importda yangilanishga ruxsat berilgan ustunlar aniq tanlanadi. created_at kabi yaratilish metama’lumoti konflikt paytida o‘zgarmasligi, updated_at esa yangilanishi mumkin.

Null qiymatlar va unique constraint qoidalari bazaga bog‘liq. Ayrim bazalarda bir nechta NULL unique indeksda konflikt hisoblanmaydi. Kompozit kalit ishlatilsa, barcha tarkibiy ustunlar yozuv identifikatsiyasining bir qismidir. Shuningdek, update triggerlari va foreign key tekshiruvlari upsert paytida ishga tushishi mumkin.

Natija va kuzatuv

Ilova ko‘pincha amal insert yoki update bo‘lganini, yakuniy ID ni va versiya qiymatini bilishi kerak. RETURNING kabi imkoniyatlar yakuniy qatorni qaytaradi. Ta’sirlangan qatorlar soni turli drayverlarda farqli talqin qilinishi mumkin, shuning uchun platforma hujjati hisobga olinadi.

Katta bulk upsert indekslarni yangilaydi, locklar hosil qiladi va write amplificationni oshiradi. Batch hajmi, konflikt ulushi va execution plan o‘lchanadi. Upsert qulay sintaksis bo‘lsa-da, noto‘g‘ri kalit yoki nazoratsiz barcha ustunni yangilash ma’lumot yo‘qotishiga olib kelishi mumkin.

Shartli yangilash

Ba’zi upsertlar mavjud qatorni har konfliktda emas, faqat yangi versiya kattaroq yoki ma’lum shart bajarilganda yangilaydi. PostgreSQL DO UPDATE ... WHERE sharti stale hodisaning yangi holat ustiga yozilishini cheklashi mumkin. Optimistic locking uchun versiya ustuni ishlatiladi. Shart bajarilmasa amal qatorni o‘zgartirmasligi mumkin; ilova qaytgan natijadan qaysi holat saqlanganini tekshiradi.

Bog‘liq tushunchalar

INSERT, UPDATE, Unique constraint, Primary key, Transaction, Race condition