MongoDB: قواعد البيانات والمجموعات
آخر تحديث: 2026-08-26
قاعدة البيانات هي حاوية للمجموعات، والمجموعة هي حاوية للوثائق — وهذا هو الهيكل الهرمي للبيانات في MongoDB.
تقدم هذه الدورة فهمًا متعمقًا للمفاهيم وقواعد التسمية وطرق إنشاء قواعد البيانات والمجموعات، بالإضافة إلى «المجموعة المحدودة» الخاصة.
1. ما ستتعلمه
- الفرق الجوهري بين قواعد البيانات والمجموعات (مساحات الأسماء)
- فلسفة التصميم غير القائمة على المخططات لمجموعات MongoDB
- قواعد التسمية والقيود المتعلقة بقواعد البيانات والمجموعات
- الفرق بين الخلق الضمني والخلق الصريح
استخدام
useوshowوdb.createCollection() - مجموعة محددة السعة (طابور دائري)
- عرض بيانات التعريف الخاصة بالمجموعات وإدارة قواعد البيانات
2. قصة حقيقية لمسؤول قاعدة بيانات
(1) المشكلة: قواعد التسمية المربكة تجعل الصيانة صعبة
ديانا هي مسؤولة قاعدة بيانات MongoDB، وهي مكلفة بإدارة قاعدة بيانات التجارة الإلكترونية الخاصة بالشركة. وقد اكتشفت ما يلي:
"لدينا أكثر من 50 قاعدة بيانات وأكثر من 500 مجموعة، تحمل أسماء متنوعة مثل:
shopdb.Products،shop-db.Products،shop-db.product_list… ولا نعرف أي منها نستخدم عند إجراء الاستعلامات، وغالبًا ما تفشل نصوصنا البرمجية الخاصة بالنسخ الاحتياطي."
الوضع الحالي الفوضوي:
| المشكلة | التأثير |
|---|---|
| قواعد تسمية غير متسقة | لا يستطيع أعضاء الفريق العثور على المجموعات |
| حروف كبيرة وصغيرة مختلطة | MongoDB تميز بين الأحرف الكبيرة والصغيرة؛ يفشل الاستعلام |
| الأحرف الخاصة | الأسماء التي تبدأ بـ $ هي كلمات محجوزة |
| لا توجد وثائق خاصة بالمخطط | يتعذر التمييز بين أنواع الحقول التي تحمل الاسم نفسه (هل «price» رقم أم سلسلة أحرف؟) |
(2) MongoDB + حل يعتمد على قواعد التسمية
وضع قواعد التسمية + التحقق من صحة المخطط.
// === Naming Conventions(Hump-style + Business Prefix)===
// ❌ Counterexample
db.Products // Uppercase without a prefix
db["shop-db.product"] // contains . and -
db.$reserved // $ Leading reserved word
// ✅ Correct Example
db.shop_products // Business Prefix + Business Name(Lowercase and underlined)
db.shop_orders
db.shop_users
// === Schema Verification(mongoose Centralized Management of Field Types)===
const ProductSchema = new mongoose.Schema({
sku: { type: String, required: true }, // Clarify String Type
price: { type: mongoose.Schema.Types.Decimal128, required: true }, // Clarify Decimal128
createdAt: { type: Date, default: Date.now } // Clarify Date Type
});
(3) الإيرادات
| البعد | التسمية غير المتسقة | التسمية القياسية |
|---|---|---|
| سهولة العثور | ❌ يصعب العثور عليه | ✅ يسهل العثور عليه |
| تكاليف الصيانة | مرتفعة | منخفضة |
| التعاون بين أعضاء الفريق | تكاليف اتصال مرتفعة | لا لبس فيه |
| النسخ الاحتياطي/الاستعادة | عرضة للأخطاء | آلية وموثوقة |
3. مفاهيم قواعد البيانات
شرح المفهوم: قاعدة البيانات هي مساحة الأسماء ذات المستوى الأعلى في MongoDB، وتُستخدم لتنظيم المجموعات ذات الصلة. يمكن أن تحتوي كل مثيل من MongoDB على عدة قواعد بيانات، وتتمتع كل قاعدة بيانات بمساحة تخزين ملفات خاصة بها، وضوابط أذونات، ومساحة فهرسة. قواعد البيانات معزولة ماديًا عن بعضها البعض، ولكن لا يمكن تنفيذ استعلامات $lookup للربط عبر قواعد البيانات المختلفة.
كيفية العمل: يخصص MongoDB مساحة ملف منفصلة لكل قاعدة بيانات (مجلد واحد لكل قاعدة بيانات ضمن محرك WiredTiger). لا يتم إنشاء قواعد البيانات فعليًّا — فعند تشغيل use shopdb، يقوم MongoDB ببساطة بتبديل السياقات؛ ولا يتم إنشاء قاعدة البيانات فعليًّا إلا عند كتابة البيانات إليها لأول مرة. ويؤدي حذف قاعدة البيانات إلى الحذف الفعلي لمساحة الملف المقابلة لها.
graph TB
A[MongoDB Server Examples] --> B[admin Database<br/>System Administration]
A --> C[config Database<br/>Sharded Cluster Metadata]
A --> D[local Database<br/>Dungeon Collection Status]
A --> E[shopdb Business Database]
A --> F[analyticsdb Analytical Database]
E --> E1[users Gathering]
E --> E2[products Gathering]
E --> E3[orders Gathering]
F --> F1[events Gathering]
F --> F2[user_behavior Gathering]
style E fill:#d4edda
| قاعدة بيانات النظام | الغرض | مرئية للمستخدمين | قابلة للكتابة |
|---|---|---|---|
| admin | إدارة النظام، مصادقة المستخدمين | ✅ | ⚠️ العمليات الإدارية فقط |
| التكوين | تكوين المجموعة المقسمة | ✅ (للقراءة فقط) | ❌ |
| محلي | حالة مجموعة النسخ المتماثلة، البيانات المحلية | ✅ (مستقلة لكل عقدة) | ⚠️ |
| اختبار | الغرض من الاختبار (تم إنشاؤه افتراضيًا) | ✅ | ✅ |
(1) ما هي قاعدة البيانات؟
قاعدة البيانات هي مساحة الأسماء من المستوى الأعلى في MongoDB، وتُستخدم لتنظيم المجموعات ذات الصلة.
graph TB
A[MongoDB Server Examples] --> B[admin Database<br/>System Administration]
A --> C[config Database<br/>Sharded Cluster Metadata]
A --> D[local Database<br/>Dungeon Collection Status]
A --> E[shopdb Business Database]
A --> F[analyticsdb Analytical Database]
E --> E1[users Gathering]
E --> E2[products Gathering]
E --> E3[orders Gathering]
F --> F1[events Gathering]
F --> F2[user_behavior Gathering]
style E fill:#d4edda
(2) 4 قواعد بيانات للنظام
تحليل النقاط الرئيسية:
adminهي قاعدة بيانات مميزة للغاية — حيث يتمتع المستخدمون الذين يتم إنشاؤهم في قسم الإدارة بامتيازات شاملة.configالبيانات الوصفية لمجموعة شرائح التخزين (تكون فارغة تقريبًا في البيئات غير المقسمة إلى شرائح)- لا يتم نسخ البيانات الواردة من
localإلى العقد الأخرى في مجموعة النسخ المتماثلة — وهذا مناسب لتخزين البيانات التي لا يلزم أن تكون متاحة إلا محليًّا. testهي قاعدة البيانات الافتراضية لـ mongosh؛ وينبغي تجنب استخدامها في بيئات الإنتاج.
(3) قواعد تسمية قواعد البيانات
// === MongoDB Database Naming Conventions ===
// ✅ Valid database names
use shopdb // Alphanumeric
use shop_db // Underline
use "shop-db" // Contains a hyphen(Quotation marks are required)
use "shop.2026" // Including periods(Quotation marks are required)
// ❌ Invalid database name
use "" // Empty string
use "shop/db" // Contains a slash
use "shop$db" // $ Introduction(Although it is legal, it is not recommended)
use "admin" // System-Reserved(Although it is available, it is not recommended)
| القاعدة | الوصف |
|---|---|
| لا يجوز أن يكون فارغًا | يجب أن يحتوي على حرف واحد على الأقل |
| لا يمكن احتوائه | / \ . " $ * < > : | ? (قيود نظام ملفات ويندوز) |
| يتم التمييز بين الأحرف الكبيرة والصغيرة | shopdb ≠ SHOPDB |
| حد الطول | 64 حرفًا (حد نظام ملفات لينكس) |
| UTF-8 | يدعم اللغة الصينية (لكن لا يُنصح باستخدامه) |
▶ المثال 1: أوامر إدارة قواعد البيانات
// === List all databases ===
show dbs
الإخراج:
TEXT 📖 للعرض فقطadmin 0.000GB config 0.000GB local 0.000GB shopdb 0.005GB test 0.000GB
// === Switch Databases ===
use shopdb
الإخراج:
TEXT 📖 للعرض فقطswitched to db shopdb
// === Display the current database ===
db
الإخراج:
TEXT 📖 للعرض فقطshopdb
// === Delete the database(Use with caution!)===
db.dropDatabase()
الإخراج:
TEXT 📖 للعرض فقط{ "dropped" : "shopdb", "ok" : 1 }
// === View Database Statistics ===
db.stats()
الإخراج:
TEXT 📖 للعرض فقط{ db: 'shopdb', collections: 5, views: 0, objects: 1250, avgObjSize: 245, dataSize: 306250, storageSize: 286720, indexes: 8, indexSize: 57344, fileSize: 67108864, nsSizeMB: 16 }
4. مفهوم المجموعات
شرح المفهوم: المجموعة هي حاوية للوثائق في MongoDB، تشبه «الجدول» في قاعدة البيانات العلائقية، ولكن مع اختلاف جوهري واحد — فالمجموعات لا تخضع لمخطط بيانات محدد، مما يعني أن الوثائق داخل المجموعة نفسها يمكن أن تحتوي على تركيبات مختلفة من الحقول. وتعد هذه المرونة إحدى نقاط القوة الأساسية لـ MongoDB، لكنها تشكل أيضًا خطرًا محتملاً (حيث تتطلب تدخل طبقة التطبيق أو التحقق من صحة المخطط لضمان جودة البيانات).
كيفية العمل: يتم تعريف المجموعات في مساحة أسماء MongoDB باسم <database>.<collection>. لا تقوم المجموعات بتخزين البيانات بنفسها — حيث يتم تخزين البيانات على شكل مستندات BSON في مساحة ملفات المجموعة، بينما تحتفظ المجموعة فقط بالبيانات الوصفية (معلومات الفهرس، وقواعد التحقق من صحة المخطط، وإعدادات الحد الأقصى، وما إلى ذلك). يتم إنشاء المجموعة ضمناً عند إدراج المستند الأول، أو يمكن إنشاؤها صراحةً باستخدام createCollection().
graph TB
A[shopdb Database] --> B[users Gathering]
A --> C[products Gathering]
A --> D[orders Gathering]
B --> B1[Document 1<br/>name: Alice<br/>age: 28]
B --> B2[Document 2<br/>name: Bob<br/>age: 32<br/>role: admin]
B --> B3[Document 3<br/>name: Charlie<br/>email: c@example.com]
style B2 fill:#f8d7da
النقاط الرئيسية: يمكن أن تحتوي المجموعة الواحدة على حقول مختلفة (بدون مخطط)؛ فالمستند 1 يحتوي على حقل age، بينما يحتوي المستند 3 على حقل email دون حقل age. وهذا يوضح مرونة MongoDB — ولكنه يعني أيضًا أنك تحتاج إلى استخدام Mongoose Schema أو Schema Validation لتقييد الحقول.
| البعد | الجدول العلائقي | مجموعة MongoDB |
|---|---|---|
| المخطط | مقيد بشدة (محدد بواسطة لغة تعريف البيانات (DDL)) | غير مقيد (بدون مخطط) |
| الحقل | يجب أن تكون الحقول متطابقة في كل صف | قد تختلف الحقول من صف لآخر |
| نوع البيانات | أنواع قوية (محددة بواسطة DDL) | أنواع ضعيفة (يتم التحقق منها أثناء التشغيل) |
| العلاقة | قيد المفتاح الخارجي | مرجع على مستوى التطبيق |
| الانضمام | دعم مدمج | $lookup (دعم محدود) |
| التوسع الأفقي | معقد | التجزئة المدمجة |
(1) ما هي المجموعة؟
المجموعة هي حاوية للمستندات في MongoDB، وهي تشبه «الجدول» في قاعدة البيانات العلائقية، ولكن دون قيود المخطط.
graph TB
A[shopdb Database] --> B[users Gathering]
A --> C[products Gathering]
A --> D[orders Gathering]
B --> B1[Document 1<br/>name: Alice<br/>age: 28]
B --> B2[Document 2<br/>name: Bob<br/>age: 32<br/>role: admin]
B --> B3[Document 3<br/>name: Charlie<br/>email: c@example.com]
style B2 fill:#f8d7da
ملاحظة: يمكن أن تحتوي المجموعة الواحدة على حقول مختلفة (بدون مخطط)؛ فالمستند 1 يحتوي على حقل «العمر»، في حين أن المستند 3 يحتوي على حقل «البريد الإلكتروني» ولكنه لا يحتوي على حقل «العمر».
(2) المجموعات مقابل الجداول العلائقية
| البعد | الجدول العلائقي | مجموعة MongoDB |
|---|---|---|
| المخطط | مقيد بشدة (محدد بواسطة DDL) | غير مقيد (بدون مخطط) |
| الحقل | يجب أن تكون الحقول متطابقة في كل صف | قد تختلف الحقول من صف لآخر |
| نوع البيانات | أنواع قوية (محددة بواسطة DDL) | أنواع ضعيفة (يتم التحقق منها أثناء التشغيل) |
| العلاقة | قيد المفتاح الخارجي | مرجع على مستوى التطبيق |
| الانضمام | دعم مدمج | $lookup (دعم محدود) |
| التوسع الأفقي | التعقيد | التجزئة المدمجة |
(3) قواعد تسمية المجموعات
// ✅ Valid collection names
db.shop_products // Alphanumeric and underscores
db["shop-products"] // Contains a hyphen(Quotation marks are required)
db.shop2026 // Contains numbers
db["shop.products"] // Including periods(Quotation marks are required)
// ❌ Invalid set names
db[""] // Empty string
db.$reserved // $ Introduction(Retain)
db["system.users"] // system. Introduction(System-Reserved)
db["shop\\products"] // Contains a backslash
▶ المثال 2: أوامر إدارة المجموعات
// === List all collections in the current database ===
show collections
// users
// products
// orders
// reviews
// === Explicitly Creating Sets ===
db.createCollection("users");
// { ok: 1 }
// === Implicit Collection Creation(Created automatically when inserted into a document)===
db.users.insertOne({ name: "Alice" });
// Automatically create the collection if it does not exist
// === Create a Fixed-Size Set(capped collection)===
db.createCollection("logs", {
capped: true,
size: 10485760, // 10 MB
max: 10000 // At most 10000 Documents
});
// { ok: 1 }
// === Delete Set ===
db.users.drop();
// true
// === View Collection Statistics ===
db.users.stats();
// {
// ns: 'shopdb.users',
// size: 1024,
// count: 50,
// avgObjSize: 20,
// storageSize: 8192,
// capped: false,
// max: null,
// ...
// }
5. الإنشاء الضمني مقابل الإنشاء الصريح
شرح المفهوم: يدعم MongoDB طريقتين لإنشاء المجموعات — الإنشاء الضمني (يتم إنشاؤها تلقائيًا عند إدراج المستندات) والإنشاء الصريح (يتم إنشاؤها يدويًّا باستخدام createCollection()). تختلف هاتان الطريقتان اختلافًا كبيرًا من حيث تجربة التطوير وأمن البيانات. يُنصح بالإنشاء الضمني خلال مرحلة التطوير (لتسريع عملية التكرار)، بينما يُنصح بالإنشاء الصريح مقترنًا بالتحقق من صحة المخطط في بيئات الإنتاج (لمنع وجود بيانات غير صحيحة).
كيفية العمل: في حالة الإنشاء الضمني، يقوم MongoDB تلقائيًا بإنشاء قاعدة البيانات والمجموعة أثناء عملية الكتابة الأولى، باستخدام الإعدادات الافتراضية (بدون مجموعة محدودة، وبدون قواعد التحقق من الصحة). أما في حالة الإنشاء الصريح، فيمكنك تحديد قواعد التحقق من صحة المخطط، وإعدادات المجموعة المحدودة، وقواعد الفرز، وغيرها مسبقًا لضمان توافق عمليات الكتابة اللاحقة مع قيود العمل.
| البعد | الإنشاء الضمني | الإنشاء الصريح |
|---|---|---|
| الصيغة | insertOne() الإنشاء التلقائي |
createCollection() |
| التحقق من صحة المخطط | ❌ لا يوجد | ✅ يمكن تعريف مخطط JSON |
| الإعداد المحدد | ❌ الإعداد الافتراضي: غير محدد | ✅ يمكن تحديده |
| حالات الاستخدام | التطوير، الاختبار | التشغيل، التحقق الدقيق من صحة البيانات |
| الأخطاء الإملائية | عرضة للأخطاء | يجب تحديدها يدويًّا |
(1) الإنشاء الضمني (موصى به للتطوير)
// 1. Switch Databases(If it doesn't exist, create it later)
use shopdb;
// 2. Insert directly into the document
db.users.insertOne({ name: "Alice" });
// Automatically Create users Gathering
// 3. View Automatically Created Collections
show collections;
// users
المزايا: بسيطة وسريعة؛ لا تتطلب إدارة يدوية
العيوب: قد يؤدي عن غير قصد إلى إنشاء مجموعات تحتوي على أخطاء إملائية (على سبيل المثال، user مقابل users)
(2) الإنشاء الصريح (موصى به للاستخدام في بيئة الإنتاج)
// 1. Create an empty set(For predefined structures)
db.createCollection("users");
db.createCollection("products");
db.createCollection("orders");
// 2. Create a collection with validation(Schema Validation)
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["email", "username"],
properties: {
email: {
bsonType: "string",
pattern: "^.+@.+$"
},
username: {
bsonType: "string",
minLength: 3,
maxLength: 30
},
age: {
bsonType: "int",
minimum: 0,
maximum: 150
}
}
}
},
validationLevel: "strict",
validationAction: "error"
});
(3) مقارنة بين الطريقتين
| البعد | الإنشاء الضمني | الإنشاء الصريح |
|---|---|---|
| الصيغة | insertOne() الإنشاء التلقائي |
createCollection() |
| التحقق من صحة المخطط | ❌ لا يوجد | ✅ يمكن تعريف مخطط JSON |
| الإعداد المحدد | ❌ الإعداد الافتراضي: غير محدد | ✅ يمكن تحديده |
| حالات الاستخدام | التطوير، الاختبار | التشغيل، التحقق الدقيق من صحة البيانات |
| الأخطاء الإملائية | عرضة للأخطاء | يجب تحديدها يدويًّا |
▶ المثال 3: مجموعة محدودة
// === Create capped collection(Circular Queue)===
db.createCollection("activity_logs", {
capped: true,
size: 10485760, // 10 MB Upper Limit
max: 100000 // At most 100,000 Documents
});
// === Insert Document(Once it's full, it will automatically overwrite the oldest entries.)===
for (let i = 0; i < 5; i++) {
db.activity_logs.insertOne({
userId: `user_${i}`,
action: "login",
timestamp: new Date()
});
}
// === Search ===
db.activity_logs.find().sort({ timestamp: -1 }).limit(5);
// === Edit capped collection size ===
db.runCommand({
collMod: "activity_logs",
cappedSize: 20971520 // Expand to 20 MB
});
// === Convert to a regular collection(Irreversible!)===
db.runCommand({
collMod: "activity_logs",
cappedSize: -1
});
الإخراج:
TEXT 📖 للعرض فقط{ ok: 1 }
حالات استخدام المجموعة المحدودة:
- نظام التسجيل (يقوم تلقائيًا بمسح السجلات القديمة)
- قائمة انتظار الرسائل (تحتفظ بآخر N رسالة)
- تدفقات البيانات في الوقت الفعلي (أسعار الأسهم، بيانات أجهزة الاستشعار)
الحالات التي لا يُنصح فيها بذلك:
- يجب تحديث الوثائق (لا يدعم نظام Capped التحديثات المباشرة التي تتجاوز الحجم الأصلي)
- الحاجة إلى حذف مستندات محددة (لا يسمح برنامج «Capped» بالحذف الانتقائي)
6. مساحات أسماء المجموعات
شرح المفهوم: مساحة الاسم هي طريقة داخلية في MongoDB لتعريف المجموعات بشكل فريد، وتتبع التنسيق <database>.<collection>. على سبيل المثال، يشير shopdb.users إلى المجموعة users في قاعدة البيانات shopdb. يستخدم محرك التخزين في MongoDB مساحات الأسماء لتحديد موقع البيانات وملفات الفهرس؛ ويساعد فهم مساحات الأسماء في فهم بنية التخزين الداخلية لـ MongoDB.
كيفية العمل: يقوم محرك التخزين WiredTiger بإنشاء ملفات منفصلة للبيانات والفهارس لكل مجموعة، مع أسماء ملفات تتضمن تجزئة لمساحة الأسماء. ويخزن ملف مساحة الأسماء (ملف .ns) البيانات الوصفية لجميع المجموعات (معلومات الفهرس، وقواعد التحقق من الصحة، وإعدادات الحد الأقصى، وما إلى ذلك). يبلغ حجم ملف مساحة الأسماء 16 ميغابايت افتراضيًا، مما يحد من عدد المجموعات التي يمكن إنشاؤها في كل قاعدة بيانات.
graph TB
A[MongoDB Namespace] --> B[Database Name.Set Name]
B --> C[shopdb.users]
B --> D[shopdb.products]
B --> E[shopdb.orders]
B --> F[analytics.events]
style A fill:#cce5ff
| البند | القيد | الوصف |
|---|---|---|
| حجم ملف مساحة الاسم | الافتراضي: 16 ميغابايت | يمكن تعديله عبر --nssize |
| عدد المجموعات/قاعدة البيانات | يتحدد حسب حجم ملف مساحة الأسماء | حوالي 24,000 (عند 16 ميغابايت) |
| إجمالي طول مساحة الاسم | ≤ 120 بايت | اسم قاعدة البيانات + "." + اسم المجموعة |
(1) بنية مساحة الأسماء
graph TB
A[MongoDB Namespace] --> B[Database Name.Set Name]
B --> C[shopdb.users]
B --> D[shopdb.products]
B --> E[shopdb.orders]
B --> F[analytics.events]
style A fill:#cce5ff
مساحة الاسم = <database>.<collection>؛ يستخدم MongoDB الملف .ns لتخزين البيانات الوصفية داخليًّا.
(2) الحد الأقصى لحجم مساحة الأسماء
| البند | القيد |
|---|---|
| حجم ملف مساحة الاسم | الافتراضي 16 ميغابايت |
| عدد المجموعات/قاعدة البيانات | يتحدد بحجم ملف مساحة الأسماء |
| ضبط حجم مساحة الأسماء | يتطلب إعادة تشغيل mongod |
(3) عرض جميع مساحات الأسماء
// === View the namespaces for all collections ===
db.getCollectionNames();
// [ 'users', 'products', 'orders', 'reviews', 'activity_logs' ]
// === Namespaces with prefixes ===
db.getCollectionInfos();
// [
// { name: 'users', type: 'collection' },
// { name: 'products', type: 'collection' },
// ...
// ]
// === View the namespace of the collection(ns) ===
db.users.stats().ns;
// 'shopdb.users'
// === Switch Sets(For long set names)===
const productsCollection = db.getCollection("products");
productsCollection.findOne();
// equivalent to db.products.findOne();
7. إدارة البيانات الوصفية للمجموعات
(1) إحصائيات المجموعة
// === Statistics for a Single Set ===
db.users.stats();
// {
// ns: 'shopdb.users', // Namespace
// size: 10240, // Data Size(Byte)
// count: 250, // Number of documents
// avgObjSize: 40, // Average Document Size
// storageSize: 12288, // Disk Usage
// capped: false, // Is it a fixed set?
// max: null, // Maximum number of documents(capped)
// maxSize: null, // Maximum size(capped)
// totalIndexSize: 16384, // Total Index Size
// indexSizes: { // Index Sizes
// _id_: 8192,
// email_1: 4096
// }
// }
// === Index Information for Sets ===
db.users.getIndexes();
// [
// { v: 2, key: { _id: 1 }, name: '_id_' },
// { v: 2, key: { email: 1 }, name: 'email_1', unique: true }
// ]
// === Aggregate Data Size(Does not include indexes)===
db.users.dataSize();
// 10240
(2) تخزين المعلومات في مجموعات
// === View the collection's WiredTiger Store Information ===
db.users.storageSize();
// 12288
// === View all namespace information for the collection ===
db.users.totalSize();
// 24576
// === Index size within the set ===
db.users.totalIndexSize();
// 16384
▶ المثال 4: برنامج نصي لفحص حالة المجموعة
// === Group Physical Exams ===
function checkCollectionHealth(collName) {
const stats = db[collName].stats();
const indexes = db[collName].getIndexes();
print(`\n=== ${collName} Health Report ===`);
print(`Number of documents: ${stats.count}`);
print(`Data Size: ${(stats.size / 1024).toFixed(2)} KB`);
print(`Average Document Size: ${stats.avgObjSize} bytes`);
print(`Disk Usage: ${(stats.storageSize / 1024).toFixed(2)} KB`);
print(`Number of Indexes: ${indexes.length}`);
print(`Index Size: ${(stats.totalIndexSize / 1024).toFixed(2)} KB`);
print(`Data/Disk Ratio: ${((stats.size / stats.storageSize) * 100).toFixed(1)}%`);
print(`Is it capped: ${stats.capped ? 'Yes' : 'No'}`);
if (stats.capped) {
print(`capped size: ${(stats.maxSize / 1024 / 1024).toFixed(2)} MB`);
print(`capped max docs: ${stats.max}`);
}
}
// Check all sets
db.getCollectionNames().forEach(checkCollectionHealth);
الإخراج:
TEXT 📖 للعرض فقط=== users Health Report === Number of documents: 250 Data Size: 10.00 KB Average Document Size: 40 bytes Disk Usage: 12.00 KB Number of Indexes: 2 Index Size: 16.00 KB Data/Disk Ratio: 83.3% Is it capped: No
8. أفضل الممارسات المتعلقة بقواعد البيانات والمجموعات
(1) مبادئ تصميم قواعد البيانات
graph TB
A[Database Partitioning] --> B[By Business Domain<br/>shopdb / analyticsdb / logdb]
A --> C[By Environment<br/>shopdb_dev / shopdb_staging / shopdb_prod]
A --> D[By Tenant<br/>shopdb_tenant1 / shopdb_tenant2]
B --> B1[✅ Recommendations]
C --> C2[⚠️ Small and Medium-Sized Projects]
D --> D3[⚠️ SaaS Multi-tenant]
(2) مبادئ تصميم الديكور المسرحي
| المبدأ | الوصف |
|---|---|
| أحرف صغيرة + شرطة سفلية | shop_orders بدلاً من ShopOrders |
| بادئة الخدمة | shop_، blog_، crm_ (لتجنب التضارب) |
| تجنب الكلمات المحجوزة | لا تستخدم أسماء تبدأ بـ system. أو $ |
| حد الطول | اسم المجموعة ≤ 120 حرفًا (بما في ذلك بادئات الفهرس) |
| المفرد مقابل الجمع | يُنصح باستخدام صيغة الجمع (orders بدلاً من order) |
(3) التحكم في عدد المجموعات
| قاعدة البيانات | عدد المجموعات الموصى بها | السبب |
|---|---|---|
| المشاريع الصغيرة | 5–20 | بسيطة وواضحة |
| المشاريع متوسطة الحجم | 20–100 | توسيع الأعمال |
| المشاريع الكبيرة | 100–500 | ملاحظة: حدود مساحة الأسماء |
| المشاريع الضخمة جدًّا | > 500 | يُنصح بتقسيمها على عدة قواعد بيانات |
▶ المثال 5: هيكل قاعدة البيانات لمشروع التجارة الإلكترونية
// === shopdb Database Structure ===
shopdb/
├── users // User Information
├── user_addresses // Shipping Address(If you need to be independent)
├── products // Products
├── product_variants // Product Variants(Color/Dimensions)
├── categories // Product Categories
├── orders // Order
├── order_items // Order Items(If the data volume is large)
├── reviews // Product Reviews
├── carts // Shopping Cart
├── coupons // Coupon
├── sessions // User Session
└── activity_logs // User Behavior Logs(capped collection)
// === analyticsdb Database Structure(Data Analysis)===
analyticsdb/
├── user_events // User Events
├── page_views // Page Views
├── conversion_data // Conversion Funnel
└── aggregated_stats // Aggregate Statistics
// === logdb Database Structure(Operations Logs)===
logdb/
├── app_logs // App Logs(capped)
├── error_logs // Error Log
└── audit_logs // Audit Log
9. تمرين عملي شامل: تهيئة قاعدة بيانات منصة التجارة الإلكترونية
(1) متطلبات السيناريو
إنشاء قاعدة بيانات MongoDB لمنصة التجارة الإلكترونية، بما في ذلك:
- الكيانات الأساسية للأعمال (المستخدمون/المنتجات/الطلبات/التقييمات)
- جمع السجلات (جمع محدود)
- البرنامج النصي لتهيئة قاعدة البيانات
(2) برنامج التهيئة
// === init-shopdb.js ===
// 1. Create a Database(Implicit)
const dbName = 'shopdb';
use(dbName);
// 2. Explicitly Creating a Core Collection(with Schema Validation)
db.createCollection('users', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['email', 'username'],
properties: {
email: {
bsonType: 'string',
pattern: '^.+@.+$'
},
username: {
bsonType: 'string',
minLength: 3,
maxLength: 30
},
role: {
enum: ['customer', 'admin', 'moderator']
}
}
}
}
});
db.createCollection('products', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['sku', 'title', 'price'],
properties: {
sku: {
bsonType: 'string',
pattern: '^[A-Z0-9-]+$'
},
price: {
bsonType: 'decimal'
}
}
}
}
});
// 3. Create a Regular Set
db.createCollection('orders');
db.createCollection('reviews');
db.createCollection('carts');
// 4. Create capped collection(Log)
db.createCollection('activity_logs', {
capped: true,
size: 10485760, // 10 MB
max: 100000 // At most 10 10,000 entries
});
// 5. Create an Index
db.users.createIndex({ email: 1 }, { unique: true });
db.users.createIndex({ username: 1 }, { unique: true });
db.users.createIndex({ createdAt: -1 });
db.products.createIndex({ sku: 1 }, { unique: true });
db.products.createIndex({ category: 1, price: 1 });
db.products.createIndex({ title: 'text', description: 'text' });
db.orders.createIndex({ userId: 1, createdAt: -1 });
db.orders.createIndex({ status: 1 });
db.reviews.createIndex({ productId: 1, createdAt: -1 });
db.reviews.createIndex({ userId: 1 });
// 6. Verification Initialization
print('=== shopdb Initialization Complete ===');
print(`Number of sets: ${db.getCollectionNames().length}`);
db.getCollectionNames().forEach(name => {
print(` - ${name}`);
});
// 7. Perform Initialization
mongosh "mongodb://localhost:27017" init-shopdb.js
(3) التحقق من بنية قاعدة البيانات
// === View the database structure ===
db.adminCommand('listCollections', { db: 'shopdb' });
// {
// cursor: {
// firstBatch: [
// { name: 'users', type: 'collection', info: { ... } },
// { name: 'products', type: 'collection', info: { ... } },
// ...
// ]
// }
// }
// === View Collection Statistics ===
db.getCollectionNames().forEach(name => {
const stats = db[name].stats();
print(`${name}: ${stats.count} docs, ${(stats.size / 1024).toFixed(2)} KB`);
});
❓ أسئلة شائعة
user مقابل users إلى إنشاء مجموعتين). في بيئات الإنتاج، نوصي بالإنشاء الصريح مقترناً بالتحقق من صحة المخطط لتجنب البيانات غير الصحيحة.$lookup على المجموعات الموجودة ضمن قاعدة البيانات نفسها. تتطلب عمليات الربط بين قواعد البيانات إجراء استعلامات متعددة على مستوى طبقة التطبيق أو استخدام Atlas Data Lake.db.collection.findOne() التحقق قبل الحذف في بيئة الإنتاج.📖 ملخص
- قاعدة البيانات هي مساحة أسماء للمجموعات، والمجموعة هي حاوية للوثائق
- يحتوي MongoDB على أربع قواعد بيانات نظام افتراضية: admin و config و local و test
- المجموعات لا تخضع لمخطط بيانات محدد؛ حيث يمكن أن تحتوي المجموعة الواحدة على حقول مختلفة.
- قواعد التسمية: أحرف صغيرة + شرطة سفلية + بادئة اسم الشركة؛ تجنب استخدام الأحرف الخاصة
- الإنشاء الضمني بسيط ولكنه عرضة للأخطاء المطبعية؛ أما الإنشاء الصريح فهو آمن ولكنه مرهق.
- قائمة ذات سعة محددة هي قائمة انتظار دائرية ذات حجم ثابت، وهي مناسبة لتسجيل البيانات وقوائم انتظار الرسائل.
- إحصاءات إجمالية:
db.collection.stats()،getIndexes()،dataSize()
📝 تمارين
-
السؤال الأساسي (⭐): أنشئ قاعدة بيانات باسم
shopdbفي Mongosh تحتوي على ثلاث مجموعات:usersوproductsوorders. اذكر جميع قواعد البيانات والمجموعات. -
السؤال الأساسي (⭐): استخدم
db.users.insertOne({...})لإنشاء مجموعة جديدة ضمنيًا (مثل "sessions") وفهم آلية الإنشاء الضمني في MongoDB. -
تمرين متقدم (⭐⭐): أنشئ مجموعة محدودة السعة
activity_logs(حجمها 5 ميغابايت، بحد أقصى 1000 مستند)، وأدخل 100 مستند، وتأكد من أن أقدم المستندات يتم استبدالها تلقائيًا. -
تمرين متقدم (⭐⭐): اكتب برنامج نصي للتهيئة
init-shopdb.jsلإنشاء مجموعة users/products/orders (مع التحقق من صحة المخطط)، وإنشاء ما لا يقل عن 5 فهارس، وإنشاء مجموعة محدودة السعة للسجلات. -
تمرين متقدم (⭐⭐): استخدم
db.collection.stats()لفحص جميع المجموعات، واكتب برنامجًا نصيًّا يُخرج تقريرًا جدوليًّا يتضمن «اسم المجموعة، وعدد المستندات، وحجم البيانات، ومتوسط حجم المستند، وعدد الفهارس». -
التحدي (⭐⭐⭐): تصميم مخطط قاعدة بيانات متعددة المستأجرين لنظام SaaS (مقسمة إلى 5 قواعد بيانات حسب المجال التجاري)، وكتابة برنامج نصي كامل للتهيئة لإنشاء جميع المجموعات والفهارس والتحقق من صحة المخطط، وإصدار تقرير التهيئة.