Embedding vs Referencing — qachon qaysinisi
Muammodan boshlaylik
Foydalanuvchining manzilini qayerda saqlash kerak?
Variant A — users document ichiga joylash:
{
"_id": "u1",
"ism": "Jasur",
"manzil": {
"shahar": "Toshkent",
"ko'cha": "Navoiy 15"
}
}
Variant B — alohida collection:
// users
{ "_id": "u1", "ism": "Jasur", "manzil_id": "m1" }
// manzillar
{ "_id": "m1", "shahar": "Toshkent", "ko'cha": "Navoiy 15" }
Qaysi biri to'g'ri? Javob: bog'liq. Bu darsda qachon qaysinisini tanlashni o'rganasiz.
Embedding nima?
Ma'lumotni boshqa document ichiga joylash.
{
"_id": "u1",
"ism": "Jasur",
"manzil": {
"shahar": "Toshkent",
"ko'cha": "Navoiy 15"
}
}
manzil — alohida collection emas, users document ichida.
Referencing nima?
Ma'lumotni alohida collection da saqlash, faqat ID sini ko'rsatish.
// users
{ "_id": "u1", "ism": "Jasur", "manzil_id": "m1" }
// manzillar
{ "_id": "m1", "shahar": "Toshkent", "ko'cha": "Navoiy 15" }
SQL da bu JOIN — users.manzil_id = manzillar._id.
Taqqoslash
EMBEDDING REFERENCING
───────── ───────────
So'rov soni 1 ta 2 ta (yoki $lookup)
Tezlik Tezroq Sekinroq
Ma'lumot hajmi Katta bo'lishi mumkin Kichik
Yangilash Har joyda yangilish Bir joyda yangilash
Dublikat Bor Yo'q
Qachon Embedding?
1. Ma'lumot faqat shu document bilan ishlatilsa
Foydalanuvchining manzilini boshqa yerda ko'rsatmaysiz — faqat u bilan birga.
{
"ism": "Jasur",
"manzil": { "shahar": "Toshkent", "ko'cha": "Navoiy 15" }
}
2. Ma'lumot kichik va o'zgarmasa
Post ning muallif nomi — post yozilganda qanday bo'lsa, shunday qolsa yaxshi. Eski postlarda eski ism ko'rinishi normal.
{
"sarlavha": "MongoDB darsi",
"muallif": { "ism": "Jasur", "avatar": "/img/jasur.jpg" }
}
3. Birga o'qilsa
Buyurtma va uning mahsulotlari — har doim birga kerak.
{
"_id": "b1",
"sana": "2024-01-15",
"mahsulotlar": [
{ "nom": "Olma", "miqdor": 2, "narx": 5000 },
{ "nom": "Nok", "miqdor": 1, "narx": 8000 }
]
}
Bitta so'rov — hamma narsa keldi.
Qachon Referencing?
1. Ma'lumot ko'p joyda ishlatilsa
Muallif bir nechta post yozadi. Muallif nomi o'zgansa — barcha postlarda yangilash kerak.
// users
{ "_id": "u1", "ism": "Jasur" }
// posts
{ "sarlavha": "Dars 1", "muallif_id": "u1" }
{ "sarlavha": "Dars 2", "muallif_id": "u1" }
{ "sarlavha": "Dars 3", "muallif_id": "u1" }
Ism o'zgansa — faqat users da bir marta yangilanadi.
2. Ma'lumot katta yoki ko'p bo'lsa
Foydalanuvchining barcha buyurtmalari — yüzlab bo'lishi mumkin. Hammani users ichiga joylash noto'g'ri.
// users
{ "_id": "u1", "ism": "Jasur" }
// orders
{ "_id": "b1", "foydalanuvchi_id": "u1", "sana": "2024-01-01" }
{ "_id": "b2", "foydalanuvchi_id": "u1", "sana": "2024-02-01" }
3. Ma'lumot mustaqil ishlatiladigan bo'lsa
Mahsulot katalogdagi mahsulot — buyurtmasiz ham ko'rsatiladi, qidiriladi, filtrlanadi.
Misol — to'g'ri va noto'g'ri
Blog post
❌ Noto'g'ri — sharhlar ichida:
{
"sarlavha": "Dars 1",
"sharhlar": [
{ "matn": "Yaxshi!", "muallif": "Ali" },
{ "matn": "Rahmat", "muallif": "Vali" }
// ... yüzlab sharh
]
}
Document 16 MB limitiga yetadi. Sharhlar alohida kerak bo'lganda ham butun post yuklanadi.
✅ To'g'ri — sharhlar alohida:
// posts
{ "_id": "p1", "sarlavha": "Dars 1" }
// comments
{ "_id": "c1", "post_id": "p1", "matn": "Yaxshi!", "muallif": "Ali" }
{ "_id": "c2", "post_id": "p1", "matn": "Rahmat", "muallif": "Vali" }
Foydalanuvchi profili
✅ Manzil — ichida (faqat shu foydalanuvchi bilan):
{
"_id": "u1",
"ism": "Jasur",
"manzil": { "shahar": "Toshkent" }
}
✅ Buyurtmalar — alohida (ko'p bo'ladi):
// users
{ "_id": "u1", "ism": "Jasur" }
// orders
{ "foydalanuvchi_id": "u1", "sana": "2024-01-01", "jami": 25000 }
Aralash yondashuv
Ko'p holatlarda ikkalasini birgalikda ishlatiladi.
{
"_id": "b1",
"foydalanuvchi_id": "u1", // ← reference (foydalanuvchi alohida)
"sana": "2024-01-15",
"mahsulotlar": [ // ← embedded (buyurtma bilan birga)
{ "nom": "Olma", "narx": 5000 },
{ "nom": "Nok", "narx": 8000 }
]
}
Foydalanuvchi — reference (profil alohida kerak). Mahsulotlar — embedded (buyurtma bilan birga o'qiladi, narx o'sha vaqtdagi narx).
Qaror qabul qilish — oddiy qoida
Savol 1: Bu ma'lumot boshqa joyda ham ishlatiladi?
YO'Q → Embedding
HA → Referencing
Savol 2: Bu ma'lumot ko'p bo'lishi mumkinmi? (100+)
YO'Q → Embedding
HA → Referencing
Savol 3: Bu ma'lumot tez-tez o'zgariladimi?
YO'Q → Embedding
HA → Referencing
Uchala savolga YO'Q bo'lsa — Embedding
Birontasiga HA bo'lsa — Referencing ni ko'rib chiqing
Tez-tez uchraydigan xatolar
Hamma narsani ichiga joylash
// ❌ — foydalanuvchi ichida yüzlab buyurtma
{
"ism": "Jasur",
"buyurtmalar": [
{ ... }, { ... }, { ... } // 500 ta bo'lib ketsa?
]
}
MongoDB document chegarasi — 16 MB. Array cheksiz o'smasligi kerak.
Hamma narsani alohida saqlash (SQL fikrlash)
// ❌ — manzil uchun alohida collection (keraksiz)
// users
{ "_id": "u1", "manzil_id": "m1" }
// manzillar
{ "_id": "m1", "shahar": "Toshkent" }
// Manzil faqat shu foydalanuvchi uchun — nima uchun alohida?
SQL da har narsa alohida jadval bo'ladi — MongoDB da bu kerak emas.
Xulosa
- Embedding — birga o'qilsa, kichik bo'lsa, boshqa joyda kerak bo'lmasa
- Referencing — ko'p joyda ishlatilsa, ko'p bo'lsa, tez-tez o'zgarsа
- Ko'p holatlarda ikkalasi birgalikda — ba'zi maydonlar ichida, ba'zilari alohida
- Document 16 MB chegarasi bor — cheksiz o'sadigan massivlarni ichiga joylaman
Keyingi dars: 14-dars — One-to-Many — embedding va referencing bilan