Schema дизайн
MongoDB schema-гүй хэдий ч сайн дизайн нь аппликейшний гүйцэтгэл, хялбар засвар үйлчилгээнд шийдвэрлэх нөлөөтэй. Гол асуулт: өгөгдлийг embedding (нэг document-д хадгалах) уу, referencing (тусдаа collection-д хадгалж холбох) уу?
Embedding — document дотор хадгалах
Холбогдох өгөгдлийг нэг document-д nested object буюу array-аар хадгалдаг.
// Хэрэглэгч + хаягийг хамт хадгалсан
{
_id: ObjectId("u1"),
username: "bold",
address: {
city: "Улаанбаатар",
district: "Баянзүрх",
street: "Энхтайваны өргөн чөлөө"
}
}
Давуу тал:
- Нэг query-д бүх мэдээлэл авна —
$lookupхэрэггүй - Уншлага хурдан
- Атомик бичлэг (нэг document-д бичнэ)
Хэрэглэх тохиолдол:
- "Дотор нь багтах" харилцаа (хаяг, профайл)
- Жижиг, тогтмол хэмжээтэй өгөгдөл
- Хамт уншигддаг өгөгдөл
Referencing — тусдаа хадгалж холбох
SQL-ийн foreign key-тэй адил ObjectId-аар холбоно.
// orders collection
{
_id: ObjectId("o1"),
userId: ObjectId("u1"), // ← users collection-тэй холбоос
amount: 50000,
product: "MongoDB гарын авлага"
}
// users collection
{
_id: ObjectId("u1"),
username: "bold"
}
Давуу тал:
- Өгөгдөл нэг газарт хадгалагдана — давхардал байхгүй
- Том, байнга өөрчлөгддөг өгөгдөлд тохиромжтой
- Тусдаа унших боломжтой
Хэрэглэх тохиолдол:
- "Олон" тал нь тусдаа уншигддаг
- Өгөгдөл байнга шинэчлэгддэг
- Том хэмжээний дагалдах мэдээлэл
1:N (нэг-олон) харилцаа
Жижиг N — embedding
// Нийтлэл + сэтгэгдэл (сэтгэгдэл 10-20 байх тохиолдол)
{
_id: ObjectId("p1"),
title: "MongoDB сурах нь",
content: "...",
comments: [
{ author: "dorj", text: "Маш сайн!", createdAt: ISODate("2025-01-10") },
{ author: "od", text: "Баярлалаа", createdAt: ISODate("2025-01-11") }
]
}
Том N — referencing
// Хэрэглэгч + захиалгууд (захиалга олон байна)
// users collection
{ _id: ObjectId("u1"), username: "bold" }
// orders collection
{ _id: ObjectId("o1"), userId: ObjectId("u1"), amount: 50000 }
{ _id: ObjectId("o2"), userId: ObjectId("u1"), amount: 25000 }
N:N (олон-олон) харилцаа
Жижиг тоо — array of ObjectIds
// Оюутан олон хичээлд элсэж болно, хичээл бүрт олон оюутан байна
// students collection
{
_id: ObjectId("s1"),
name: "Болд",
enrolledCourses: [
ObjectId("c1"), // MongoDB
ObjectId("c2") // JavaScript
]
}
Завсрын collection
// enrollments — завсрын холбоос collection
{
_id: ObjectId("..."),
studentId: ObjectId("s1"),
courseId: ObjectId("c1"),
enrolledAt: ISODate("2025-01-15"),
grade: "A"
}
Завсрын collection-ийн давуу тал: холбоос дээр нэмэлт мэдээлэл (grade, enrolledAt) хадгалж болно.
Anti-pattern: Unbounded array
Хязгааргүй өсдөг array бол хамгийн аюултай anti-pattern. MongoDB document-ийн хэмжээний хязгаар 16MB:
// ❌ Муу — followers жагсаалт хязгааргүй өснө
{
_id: ObjectId("u1"),
username: "bold",
followers: [
ObjectId("u2"),
ObjectId("u3"),
// ... хэдэн сая хэрэглэгч нэмэгдвэл document 16MB-с хэтрэнэ
]
}
// ✅ Сайн — тусдаа collection
// follows collection
{ followerId: ObjectId("u2"), followingId: ObjectId("u1") }
{ followerId: ObjectId("u3"), followingId: ObjectId("u1") }
Хэзээ яг алийг нь сонгох вэ?
| Нөхцөл | Embedding | Referencing | | ------------------- | --------- | ----------- | | Хамт уншигддаг | ✅ | — | | Тусдаа уншигддаг | — | ✅ | | Тогтмол хэмжээ | ✅ | — | | Хязгааргүй өснө | ❌ | ✅ | | Байнга шинэчлэгддэг | — | ✅ | | Давхардал хамаагүй | ✅ | — |
Практикт ихэнх MongoDB схем нь хоёуланг хосолдог — зарим мэдээллийг embedding, зарим мэдээллийг referencing ашиглан хадгалдаг.
Дараагийн хичээлд:
Document validation ашиглан collection-д оруулах өгөгдлийн форматыг хэрхэн баталгаажуулах талаар үзнэ.