تعدّد المستأجرين: كيف تخدم مئات العملاء من نظام واحد
قاعدة بيانات لكل عميل أم صف لكل عميل؟ القرار الذي يحدّد تكلفتك وسرعتك وحدود نموّك لسنوات.
أول قرار معماري في أي منصة تخدم أكثر من عميل هو: أين ينتهي عميل ويبدأ الآخر؟ الإجابة تبدو تقنية بحتة، لكنها تحدّد فاتورتك الشهرية، وزمن إطلاق كل ميزة، وما يحدث حين يطلب عميل كبير تقريراً أمنياً.
ثلاثة نماذج، لا نموذج واحد صحيح
- قاعدة بيانات لكل مستأجر: أقصى عزل، وأسهل استرجاع لعميل بعينه، وأغلى تكلفة وأبطأ هجرة — عليك تشغيل الترحيل على كل قاعدة.
- مخطط (schema) لكل مستأجر: وسط عملي على PostgreSQL، لكن عدد المخططات يصبح عبئاً بعد بضع مئات.
- صف مشترك مع عمود tenant_id: أرخص وأسرع نمواً، وكل الخطر يتركّز في مكان واحد — نسيان شرط واحد في استعلام واحد.
لماذا يفوز الصف المشترك عادةً
العملاء الصغار هم الأغلبية في أي منتج SaaS، ومعظمهم يخزّن ميغابايتات لا غيغابايتات. تخصيص قاعدة بيانات لكل واحد يعني دفع ثمن العزل لعميل لن يستهلك ١٪ منه. ابدأ بالصف المشترك، واحتفظ بالعزل الكامل كخيار مدفوع لمن يطلبه.
اجعل العزل قراراً للنظام لا للمطوّر
أخطر ما في الصف المشترك أن نسيان `WHERE tenant_id = ?` لا يُسقط النظام، بل يُظهر بيانات عميل لعميل آخر بصمت. لا تعتمد على الانضباط البشري: افرض العزل في طبقة أدنى من الاستعلام — سياسات أمان على مستوى الصف (RLS)، أو طبقة وصول للبيانات لا يمكن استدعاؤها بدون سياق المستأجر.
أي حاجز أمني يعتمد على تذكّر المطوّر هو حاجز ستنساه مرة واحدة، وهي المرة التي تهمّ.
المفاتيح المشتركة والحدود المشتركة
العزل المنطقي لا يمنع مستأجراً من التأثير على غيره. استعلام ثقيل من عميل واحد يبطئ الجميع. ضع حدوداً لكل مستأجر على المعدّل وحجم الرفع وعدد الوظائف المتزامنة، وراقب الاستهلاك منسوباً للمستأجر لا للنظام ككل.
الهجرات هي الاختبار الحقيقي
- أضف العمود قابلاً للإفراغ أولاً، وانشر الكود الذي يكتب فيه.
- املأ البيانات القديمة على دفعات، لا في معاملة واحدة.
- بدّل القراءة إلى العمود الجديد خلف مفتاح تشغيل.
- احذف القديم بعد أن تتأكد من عدم وجود قارئ.
هذا الترتيب يبدو بطيئاً حتى أول مرة تُضطر فيها للتراجع عن هجرة على بيانات حيّة لمئات العملاء. الأداة العملية لفرض العزل في طبقة البيانات هي سياسات الأمان على مستوى الصف في PostgreSQL، وهي تجعل الشرط جزءاً من الجدول لا من الاستعلام.
متى تراجع القرار
راجع النموذج حين يطلب عميل موقعاً جغرافياً محدداً لبياناته، أو حين يتجاوز مستأجر واحد ١٠٪ من حجم قاعدتك، أو حين يصبح تقرير الامتثال شرطاً للبيع. عندها يصبح العزل الفيزيائي ميزة تُباع لا تكلفة تُتحمّل.
للتوسّع في أنماط تعدّد المستأجرين وحدودها، دليل مايكروسوفت المعماري للمنتجات متعددة المستأجرين من أوفى المراجع المتاحة. وإن كنت تختار النموذج الآن، تحدّث إلينا قبل أن يثبت القرار في الكود — تغييره لاحقاً هجرة لا إعادة كتابة.
أسئلة شائعة
هل RLS بديل عن التحقق في التطبيق؟
هو الحاجز الأخير لا الوحيد. اجمع بينهما: التطبيق يمنع الخطأ الشائع، وسياسة قاعدة البيانات تمنع الخطأ الذي أفلت.
كيف أختبر العزل فعلياً؟
اكتب اختباراً ينشئ مستأجرين ويحاول قراءة بيانات الأول بسياق الثاني عبر كل نقطة نهاية. أي نجاح في القراءة هو فشل في الاختبار.
متى أنقل عميلاً إلى قاعدة منفصلة؟
حين يصبح حجمه أو متطلباته الأمنية استثناءً يكلّف بقية العملاء أداءً أو تعقيداً.