MongoDB: قواعد البيانات والمجموعات

آخر تحديث: 2026-08-26

قاعدة البيانات هي حاوية للمجموعات، والمجموعة هي حاوية للوثائق — وهذا هو الهيكل الهرمي للبيانات في MongoDB.

تقدم هذه الدورة فهمًا متعمقًا للمفاهيم وقواعد التسمية وطرق إنشاء قواعد البيانات والمجموعات، بالإضافة إلى «المجموعة المحدودة» الخاصة.

1. ما ستتعلمه



2. قصة حقيقية لمسؤول قاعدة بيانات

(1) المشكلة: قواعد التسمية المربكة تجعل الصيانة صعبة

ديانا هي مسؤولة قاعدة بيانات MongoDB، وهي مكلفة بإدارة قاعدة بيانات التجارة الإلكترونية الخاصة بالشركة. وقد اكتشفت ما يلي:

"لدينا أكثر من 50 قاعدة بيانات وأكثر من 500 مجموعة، تحمل أسماء متنوعة مثل: shopdb.Products، shop-db.Products، shop-db.product_list… ولا نعرف أي منها نستخدم عند إجراء الاستعلامات، وغالبًا ما تفشل نصوصنا البرمجية الخاصة بالنسخ الاحتياطي."

الوضع الحالي الفوضوي:

المشكلة التأثير
قواعد تسمية غير متسقة لا يستطيع أعضاء الفريق العثور على المجموعات
حروف كبيرة وصغيرة مختلطة MongoDB تميز بين الأحرف الكبيرة والصغيرة؛ يفشل الاستعلام
الأحرف الخاصة الأسماء التي تبدأ بـ $ هي كلمات محجوزة
لا توجد وثائق خاصة بالمخطط يتعذر التمييز بين أنواع الحقول التي تحمل الاسم نفسه (هل «price» رقم أم سلسلة أحرف؟)

(2) MongoDB + حل يعتمد على قواعد التسمية

وضع قواعد التسمية + التحقق من صحة المخطط.

JAVASCRIPT
// === 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 ببساطة بتبديل السياقات؛ ولا يتم إنشاء قاعدة البيانات فعليًّا إلا عند كتابة البيانات إليها لأول مرة. ويؤدي حذف قاعدة البيانات إلى الحذف الفعلي لمساحة الملف المقابلة لها.

100%
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، وتُستخدم لتنظيم المجموعات ذات الصلة.

100%
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 قواعد بيانات للنظام

تحليل النقاط الرئيسية:

  1. admin هي قاعدة بيانات مميزة للغاية — حيث يتمتع المستخدمون الذين يتم إنشاؤهم في قسم الإدارة بامتيازات شاملة.
  2. config البيانات الوصفية لمجموعة شرائح التخزين (تكون فارغة تقريبًا في البيئات غير المقسمة إلى شرائح)
  3. لا يتم نسخ البيانات الواردة من local إلى العقد الأخرى في مجموعة النسخ المتماثلة — وهذا مناسب لتخزين البيانات التي لا يلزم أن تكون متاحة إلا محليًّا.
  4. test هي قاعدة البيانات الافتراضية لـ mongosh؛ وينبغي تجنب استخدامها في بيئات الإنتاج.

(3) قواعد تسمية قواعد البيانات

JAVASCRIPT
// === 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)
القاعدة الوصف
لا يجوز أن يكون فارغًا يجب أن يحتوي على حرف واحد على الأقل
لا يمكن احتوائه / \ . " $ * < > : | ? (قيود نظام ملفات ويندوز)
يتم التمييز بين الأحرف الكبيرة والصغيرة shopdbSHOPDB
حد الطول 64 حرفًا (حد نظام ملفات لينكس)
UTF-8 يدعم اللغة الصينية (لكن لا يُنصح باستخدامه)

▶ المثال 1: أوامر إدارة قواعد البيانات

JAVASCRIPT
// === List all databases ===
show dbs

الإخراج:

TEXT 📖 للعرض فقط
admin       0.000GB
config      0.000GB
local       0.000GB
shopdb      0.005GB
test        0.000GB
JAVASCRIPT

// === Switch Databases ===
use shopdb

الإخراج:

TEXT 📖 للعرض فقط
switched to db shopdb
JAVASCRIPT

// === Display the current database ===
db

الإخراج:

TEXT 📖 للعرض فقط
shopdb
JAVASCRIPT

// === Delete the database(Use with caution!)===
db.dropDatabase()

الإخراج:

TEXT 📖 للعرض فقط
{ "dropped" : "shopdb", "ok" : 1 }
JAVASCRIPT

// === 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().

100%
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، وهي تشبه «الجدول» في قاعدة البيانات العلائقية، ولكن دون قيود المخطط.

100%
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) قواعد تسمية المجموعات

JAVASCRIPT
// ✅ 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: أوامر إدارة المجموعات

JAVASCRIPT
// === 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) الإنشاء الضمني (موصى به للتطوير)

JAVASCRIPT
// 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) الإنشاء الصريح (موصى به للاستخدام في بيئة الإنتاج)

JAVASCRIPT
// 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: مجموعة محدودة

JAVASCRIPT
// === 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 }

حالات استخدام المجموعة المحدودة:

الحالات التي لا يُنصح فيها بذلك:



6. مساحات أسماء المجموعات

شرح المفهوم: مساحة الاسم هي طريقة داخلية في MongoDB لتعريف المجموعات بشكل فريد، وتتبع التنسيق <database>.<collection>. على سبيل المثال، يشير shopdb.users إلى المجموعة users في قاعدة البيانات shopdb. يستخدم محرك التخزين في MongoDB مساحات الأسماء لتحديد موقع البيانات وملفات الفهرس؛ ويساعد فهم مساحات الأسماء في فهم بنية التخزين الداخلية لـ MongoDB.

كيفية العمل: يقوم محرك التخزين WiredTiger بإنشاء ملفات منفصلة للبيانات والفهارس لكل مجموعة، مع أسماء ملفات تتضمن تجزئة لمساحة الأسماء. ويخزن ملف مساحة الأسماء (ملف .ns) البيانات الوصفية لجميع المجموعات (معلومات الفهرس، وقواعد التحقق من الصحة، وإعدادات الحد الأقصى، وما إلى ذلك). يبلغ حجم ملف مساحة الأسماء 16 ميغابايت افتراضيًا، مما يحد من عدد المجموعات التي يمكن إنشاؤها في كل قاعدة بيانات.

100%
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) بنية مساحة الأسماء

100%
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) عرض جميع مساحات الأسماء

JAVASCRIPT
// === 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) إحصائيات المجموعة

JAVASCRIPT
// === 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) تخزين المعلومات في مجموعات

JAVASCRIPT
// === 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: برنامج نصي لفحص حالة المجموعة

JAVASCRIPT
// === 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) مبادئ تصميم قواعد البيانات

100%
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: هيكل قاعدة البيانات لمشروع التجارة الإلكترونية

JAVASCRIPT
// === 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) برنامج التهيئة

JAVASCRIPT
// === 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) التحقق من بنية قاعدة البيانات

JAVASCRIPT
// === 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`);
});


❓ أسئلة شائعة

س ما الفرق الأساسي بين المجموعة (collection) والجدول (table)؟
ج الجدول مرتبط ارتباطًا وثيقًا بالمخطط (يتم تعريف أنواع الحقول بواسطة لغة DDL)، في حين أن المجموعة لا تخضع لمخطط (يمكن أن تحتوي المجموعة نفسها على حقول مختلفة). لا تقوم MongoDB بالتحقق من صحة الحقول على مستوى قاعدة البيانات؛ بل يتم التحكم في ذلك من خلال طبقة التطبيق (Mongoose) أو ميزة التحقق من صحة المخطط (Schema Validation).
س ما هي مخاطر إنشاء المجموعات بشكل ضمني؟
ج خطر حدوث أخطاء إملائية (على سبيل المثال، قد يؤدي user مقابل users إلى إنشاء مجموعتين). في بيئات الإنتاج، نوصي بالإنشاء الصريح مقترناً بالتحقق من صحة المخطط لتجنب البيانات غير الصحيحة.
س ما هي قيود المجموعة المحدودة الحجم؟
ج (1) لا يمكنك تحديث المستندات في مكانها بما يتجاوز الحجم الأصلي للمستند؛ (2) لا يمكنك حذف المستندات بشكل انتقائي؛ (3) لا يمكنك تقسيم المجموعة إلى أجزاء. وهي مناسبة لحالات مثل السجلات وقوائم انتظار الرسائل.
س هل يمكنني استخدام الأحرف الصينية في أسماء قواعد البيانات؟
ج هذا ممكن من الناحية التقنية (UTF-8)، لكن يُنصح بشدة بعدم القيام بذلك. فأدوات واجهة سطر الأوامر (CLI) ونصوص النسخ الاحتياطي وأدوات الجهات الخارجية لا تدعم الأحرف الصينية بشكل جيد، مما قد يؤدي إلى كوارث تشغيلية. نوصي باستخدام الأحرف الإنجليزية وعلامات التسطير السفلية حصريًّا.
س هل يمكنني إجراء عمليات ربط (JOIN) بين قواعد البيانات؟
ج لا. يقتصر استخدام $lookup على المجموعات الموجودة ضمن قاعدة البيانات نفسها. تتطلب عمليات الربط بين قواعد البيانات إجراء استعلامات متعددة على مستوى طبقة التطبيق أو استخدام Atlas Data Lake.
س هل يمكن استعادة مجموعة بعد حذفها؟
ج لا يمكن استعادتها مباشرةً ما لم تكن لديك نسخة احتياطية (mongodump) أو ما لم يتم تمكين النسخ المتماثل لـ oplog. تأكد من db.collection.findOne() التحقق قبل الحذف في بيئة الإنتاج.
س هل هناك حد أقصى لعدد قواعد البيانات؟
ج لا توجد قيود تقنية صارمة؛ حيث يتحدد العدد بحجم ملف مساحة الأسماء (16 ميغابايت افتراضيًّا). في بيئة الإنتاج، نوصي بعدد يتراوح بين 5 و20 قاعدة بيانات؛ فوجود عدد كبير جدًّا منها سيزيد من تعقيد عملية الإدارة.

📖 ملخص


📝 تمارين

  1. السؤال الأساسي (⭐): أنشئ قاعدة بيانات باسم shopdb في Mongosh تحتوي على ثلاث مجموعات: users وproducts وorders. اذكر جميع قواعد البيانات والمجموعات.

  2. السؤال الأساسي (⭐): استخدم db.users.insertOne({...}) لإنشاء مجموعة جديدة ضمنيًا (مثل "sessions") وفهم آلية الإنشاء الضمني في MongoDB.

  3. تمرين متقدم (⭐⭐): أنشئ مجموعة محدودة السعة activity_logs (حجمها 5 ميغابايت، بحد أقصى 1000 مستند)، وأدخل 100 مستند، وتأكد من أن أقدم المستندات يتم استبدالها تلقائيًا.

  4. تمرين متقدم (⭐⭐): اكتب برنامج نصي للتهيئة init-shopdb.js لإنشاء مجموعة users/products/orders (مع التحقق من صحة المخطط)، وإنشاء ما لا يقل عن 5 فهارس، وإنشاء مجموعة محدودة السعة للسجلات.

  5. تمرين متقدم (⭐⭐): استخدم db.collection.stats() لفحص جميع المجموعات، واكتب برنامجًا نصيًّا يُخرج تقريرًا جدوليًّا يتضمن «اسم المجموعة، وعدد المستندات، وحجم البيانات، ومتوسط حجم المستند، وعدد الفهارس».

  6. التحدي (⭐⭐⭐): تصميم مخطط قاعدة بيانات متعددة المستأجرين لنظام SaaS (مقسمة إلى 5 قواعد بيانات حسب المجال التجاري)، وكتابة برنامج نصي كامل للتهيئة لإنشاء جميع المجموعات والفهارس والتحقق من صحة المخطط، وإصدار تقرير التهيئة.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%