قارن النماذج لا العلامات
السؤال المفيد ليس أي قاعدة بيانات أسرع، بل أي نموذج يلائم نمط الوصول. تكافئ العلائقية الكيانات المستقرة ذات العلاقات الكثيرة والتقارير العابرة: الطلبات والفواتير والصلاحيات والمخزون. وتكافئ الوثائقية التجميعات التي تُقرأ وتُكتب كوحدة ويتفاوت شكلها حسب المستأجر: كتالوجات منتجات بسمات لكل تصنيف، وحمولات أحداث، ومسودات ينشئها المستخدمون. كلتاهما تدعم JSON، فالقرار يتعلق بمركز الثقل لا بحد صارم.
ارسم خمسة استعلامات هي الأكثر تكرارًا وخمسة هي الأكثر إثارة للقلق. فإن تضمنت المقلقة ربط أربعة جداول وتجميعًا شهريًا، فمحرّك علائقي بمخطّط استعلامات سيخدمها. وإن تضمنت جلب تجميعة واحدة بمفتاح وإعادتها كاملة، فمخزن وثائقي يتجنب الربط الكائني العلائقي تمامًا. اكتب القائمة قبل أي اختبار أداء.
المعاملات والقيود
يفرض PostgreSQL المفاتيح الأجنبية وقيود التفرّد وقيود التحقق وعزل التسلسل داخل محرّك معاملات ناضج. ويدعم MongoDB معاملات متعددة الوثائق ضمن مجموعة نسخ أو عنقود مُجزّأ، لكن فلسفة النمذجة تتوقع أن تجمع البيانات المرتبطة في وثيقة واحدة فنادرًا ما تحتاج المعاملات. والفرق ثقافي وعملي: المخططات العلائقية تدعو إلى التكامل بين الكيانات، والوثائقية تدعو إلى التضمين والتكرار.
التكرار ليس خطأ تلقائيًا؛ إنه مقايضة بين كلفة الكتابة وكلفة القراءة. فإن ضمن الطلب بنوده، استلزم تغيير بند إعادة كتابة الطلب لكن قراءته بحث واحد. وإن كانت البنود صفوفًا منفصلة، قرأت الاستعلامات بربط لكن التحديثات جراحية. اختر حسب الأكثر تكرارًا وهل للتجميعة دورة حياة مستقلة عن أصلها.
أنماط الاستعلام والفهارس
فهارس MongoDB قائمة على B-tree ويختارها المطوّر صراحةً، فيصبح شكل الاستعلام ظاهرًا في مراجعة الكود. أما فهارس PostgreSQL فأنواع متعددة: B-tree للتساوي والنطاقات، وGIN للمصفوفات والبحث النصي، وGiST للبيانات الهندسية، وBRIN للجداول الكبيرة القابلة للإضافة فقط. وكلتا القاعدتين تفشل بالطريقة نفسها حين لا يطابق الفهرس الاستعلام: مسح كامل ينجح في بيئة الاختبار وينهار تحت حجم الإنتاج.
ركّب مفاتيح الفهرس بترتيب تصفية الاستعلام وترتيبه، وأكّد ذلك بـ EXPLAIN ANALYZE لا بالحدس. فالفهرس المركّب على (tenant_id, status, created_at) يخدم قائمة لمستأجر مرتبة بالتاريخ، بينما فهرس منفصل على status نادرًا ما يستحق كلفة كتابته. راقب البادئات منخفضة الانتقائية والترتيب بعد التصفية، فهو يفرض ترتيبًا في الذاكرة متى تجاوزت مجموعة العمل سعة الذاكرة.
-- تأكد من استخدام الفهرس وأن الترتيب ليس في الذاكرة.
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, status, created_at
FROM orders
WHERE tenant_id = $1
AND status = 'open'
ORDER BY created_at DESC
LIMIT 50;تطور المخطط والهجرات
تغيّر هجرات PostgreSQL البنية والبيانات تحت مخطط معروف، وهو أمر صريح لكنه يتطلب حذرًا في الجداول الكبيرة. إضافة عمود بقيمة افتراضية رخيصة في الإصدارات الحديثة، لكن إضافة قيد NOT NULL دون مسار متحقق منه تقفل الجدول. استخدم نمط التوسيع والتقليص: أضف العمود القابل للفراغ، واملأه على دفعات، وأضف القيد كغير مُتحقَّق، ثم تحقق منه، وأزل العمود القديم في إصدار لاحق. ونفّذ الملء خارج ساعات الذروة وراقب تأخر النسخ.
تستوعب المخازن الوثائقية الحقول الإضافية دون هجرة، وهو مريح فعلًا في البداية ومحفوف بالمخاطر لاحقًا. فبعد عامين تحمل المجموعة ستة أجيال من الوثائق وعليك أن تتعامل معها كلها في كل استعلام. أضف إصدارًا لكل وثيقة بحقل schemaVersion، وتحقق من الكتابات مقابل الشكل الحالي، ونفّذ هجرة كسولة تعيد كتابة الوثائق القديمة عند لمسها لاحقًا.
شغّل ما تستطيع رصده
كلا النظامين متطلّب تشغيليًا عند التوسع. يحتاج PostgreSQL إلى تجميع الاتصالات وضبط التنظيف التلقائي ومراقبة تأخر النسخ والانتباه للتضخم. ويحتاج MongoDB إلى صحة مجموعة النسخ واختيار مفتاح التجزئة والوعي بأثر بناء الفهرس على إنتاجية الأساس. ومفتاح تجزئة منخفض التفرّد يُنشئ جزءًا ساخنًا، وطبقة تجميع سيئة الاختيار تستنفد الاتصالات تحت الحمل. احسب حجم المجموعة من حد اتصالات قاعدة البيانات لا من عدد نسخ التطبيق.
اختر المخزن الذي يستطيع فريقك تشغيله يوم سبت. فالأدوات والنسخ الاحتياطية والمعرفة المؤسسية أهم من نسب اختبار أداء تفترض عتادًا مثاليًا. دوّن المخاطر التشغيلية لكل مرشح، وحدّد من يكون على المناوبة، وتدرّب على الاستعادة. فقاعدة بيانات تفهمها بعمق تحت الضغط أفضل من أخرى فازت باختبار إنتاجية اصطناعي في مقال.
