Schema Patterns — Bucket, Outlier, Computed, Subset
Muammodan boshlaylik
Ba'zi muammolar oddiy embedding yoki referencing bilan hal bo'lmaydi. Ilovangiz o'sib boradi — ma'lumot ko'payadi, so'rovlar sekinlashadi.
Bu darsda real loyihalarda ishlatiladigan 4 ta schema pattern — har birining muammo va yechimi.
Bucket Pattern
Muammo
Har soniyada sensor harorat o'lchaydi. Bir yilda 31 million yozuv. Har o'lchov uchun alohida document — collection katta, so'rovlar sekin.
// ❌ Har o'lchov — alohida document (31 million ta)
{ "sensor": "s1", "vaqt": "2024-01-01T00:00:01", "harorat": 22.5 }
{ "sensor": "s1", "vaqt": "2024-01-01T00:00:02", "harorat": 22.6 }
{ "sensor": "s1", "vaqt": "2024-01-01T00:00:03", "harorat": 22.4 }
Yechim
Bir soatlik o'lchashlarni bitta document ga yig'amiz.
// ✅ Bir soatlik o'lchashlar — bitta document
{
"sensor": "s1",
"soat": "2024-01-01T00:00:00",
"o_lchashlar": [
{ "daqiqa": 0, "harorat": 22.5 },
{ "daqiqa": 1, "harorat": 22.6 },
{ "daqiqa": 2, "harorat": 22.4 }
],
"min": 22.1,
"max": 23.0,
"o_rtacha": 22.5
}
Oldin: 31 000 000 ta document
Keyin: 525 600 ta document
↑ 60 marta kamroq
// Yangi o'lchov qo'shish
db.sensorlar.updateOne(
{ sensor: "s1", soat: "2024-01-01T00:00:00" },
{ $push: { o_lchashlar: { daqiqa: 3, harorat: 22.7 } } },
{ upsert: true }
)
Qachon ishlatiladi: Vaqt bo'yicha keluvchi ma'lumot — sensor, analytics, server loglari.
Outlier Pattern
Muammo
Ko'pchilik foydalanuvchi 50-100 ta post yozadi. Lekin mashhur blogger 500 000 ta post yozdi. Uning document i 16 MB dan oshib ketdi.
// ❌ — 500 000 ta post_id bitta documentda
{
"_id": "u_yasmin",
"ism": "Yasmin",
"post_ids": ["p1", "p2", "p3", ...] // 500 000 ta → 16 MB!
}
Yechim
Asosiy document da faqat so'nggi postlar. Qolganlar — alohida overflow document da.
// Asosiy document — so'nggi postlar
{
"_id": "u_yasmin",
"ism": "Yasmin",
"post_ids": ["p499998", "p499999", "p500000"],
"overflow": true // ← yana ko'proq bor
}
// Overflow document — eski postlar
{
"foydalanuvchi_id": "u_yasmin",
"post_ids": ["p1", "p2", ..., "p499997"]
}
Ko'pchilik foydalanuvchi: overflow yo'q, oddiy document
Mashhur blogger: overflow: true, alohida document
Qachon ishlatiladi: Ko'pchilik uchun ma'lumot o'rtacha, lekin nodir holatlarda juda ko'p bo'lganda.
Computed Pattern
Muammo
Bosh sahifada: "Bugungi eng ko'p sotilgan 10 ta mahsulot". Har bir sahifa ochilganda millionlab buyurtma hisoblanadi — sekin.
Har foydalanuvchi bosh sahifani ochsa → 1 000 000 buyurtma hisoblanadi
1000 foydalanuvchi bir vaqtda → 1 000 000 000 ta hisob-kitob
Yechim
Natijani oldindan hisoblab, alohida document da saqlash. Sahifa ochilganda — faqat o'sha documentni o'qish.
// top_mahsulotlar — oldindan hisoblangan
{
"sana": "2024-01-15",
"top10": [
{ "nom": "iPhone 15", "sotildi": 1250 },
{ "nom": "AirPods", "sotildi": 980 },
{ "nom": "MacBook", "sotildi": 640 }
]
}
// ✅ Bosh sahifa uchun — bitta so'rov, darhol
db.top_mahsulotlar.findOne({ sana: "2024-01-15" })
So'rov: 1 ms (tayyor natija)
vs
So'rov: 800 ms (har safar millionlab buyurtmani hisoblash)
Hisoblash esa orqa fonda — har soatda yoki har kecha bajariladi. Foydalanuvchi kutmaydi.
Qachon ishlatiladi: Ko'p o'qiladigan, lekin kamdan-kam o'zgaradigan statistika — ko'rishlar soni, reyting, oylik hisobot.
Subset Pattern
Muammo
Mahsulot sahifasida 5000 ta sharh bor. Sahifa ochilganda faqat so'nggi 3 tasi ko'rsatiladi. Lekin hamma sharh yuklanadi — isrof.
// ❌ — 5000 ta sharh bitta documentda
{
"_id": "m1",
"nom": "iPhone 15",
"sharhlar": [
{ "matn": "Zo'r!", "baho": 5 },
{ "matn": "Yaxshi", "baho": 4 }
// ... 5000 ta
]
}
Yechim
Asosiy document da faqat so'nggi 3 ta sharh. Barcha sharhlar — alohida collection da.
// mahsulotlar — faqat so'nggi 3 ta sharh
{
"_id": "m1",
"nom": "iPhone 15",
"narx": 12000000,
"so_nggi_sharhlar": [
{ "matn": "Zo'r!", "baho": 5 },
{ "matn": "Yaxshi", "baho": 4 },
{ "matn": "Normal", "baho": 3 }
],
"o_rtacha_baho": 4.2,
"sharhlar_soni": 5000
}
// sharhlar collection — barcha sharhlar
{ "mahsulot_id": "m1", "matn": "Zo'r!", "baho": 5 }
{ "mahsulot_id": "m1", "matn": "Yaxshi", "baho": 4 }
// ... 5000 ta
// Birinchi yuklanish — tez, kichik document
db.mahsulotlar.findOne({ _id: "m1" })
// "Ko'proq sharhlar" bosilganda
db.sharhlar.find({ mahsulot_id: "m1" }).sort({ sana: -1 })
Qachon ishlatiladi: Ko'p ma'lumotdan dastlab faqat bir qismi ko'rsatilganda — sharhlar, xabarlar, faollik tarixi.
Xulosa
Pattern Muammo Yechim
───────── ────────────────────────── ─────────────────────
Bucket Millionlab kichik yozuv Vaqt bo'yicha guruhlash
Outlier Ba'zi documentlar g'ayritabiiy Asosiy + overflow
Computed Tez-tez hisob-kitob Oldindan hisoblash
Subset Katta document, oz qism kerak Asosiy + to'liq alohida
Keyingi dars: 17-dars — Schema Validation — $jsonSchema, validator