قواعد بيانات Multi-Tenant SaaS: قاعدة مشتركة أم Database لكل Workspace؟
- نُشر في
- مدة القراءة
- 14 دقائق قراءة
الـMulti-Tenancy مش مجرد إضافة tenant_id. اختيار Shared Database أوSchema لكل Tenant أوDatabase لكل Workspace يغيّر العزل، الـmigrations، الـbackups، الـanalytics، ضغط الاتصالات وتكلفة التشغيل. هنا Framework عملي لاختيار الـarchitecture قبل ما تغييرها يبقى مكلفًا. #SaaS #MultiTenancy #DatabaseArchitecture #PostgreSQL #SoftwareArchitecture #Laravel #Golang
قواعد بيانات Multi-Tenant SaaS: قاعدة مشتركة أم Database لكل Workspace؟
واحد من أول Architecture Decisions في أي SaaS ممكن يتحول لواحد من أصعب القرارات في التغيير بعدين:
بيانات كل Customer هتعيش فين؟
الإجابة الأبسط غالبًا Shared Database فيها tenant_id أو workspace_id.
وده ممكن يكون الاختيار الصح فعلًا.
لكن مش الاختيار الوحيد.
في الطرف الآخر، كل Workspace ممكن يكون لها Database مستقلة. وبين الاثنين فيه Schema-per-Tenant وHybrid Models تجمع أكثر من Approach.
مفيش اختيار صحيح لكل المنتجات.
السؤال الأفضل:
أنهي Tenancy Boundary تناسب متطلبات العزل وطريقة التشغيل والScale المتوقع للمنتج؟
Database Topology جزء واحد فقط من Multi-Tenancy. Authentication وAuthorization وQueues وCache Keys وObject Storage وSearch وLogs وBackground Jobs وIntegrations لازم تحترم نفس الـBoundary.
أشهر 3 Database Models
1. Shared Database + Shared Tables
كل Workspaces تستخدم نفس Database ونفس Tables، وكل Row فيها Tenant Identifier.
bookings
-------------------------
id
workspace_id
customer_id
status
...
تشغيليًا ده بسيط وغالبًا Efficient.
Migration واحدة تحدث Schema واحدة. Cross-tenant Analytics سهلة. Connection Management متوقعة. Infrastructure Overhead لكل Customer قليلة.
لكن Isolation تعتمد جدًا على صحة Application Code.
Tenant Condition ناقصة في Query غلط ممكن تتحول إلى Data-isolation Incident.
2. Shared Database + Separate Schemas
Customers يشتركوا في Database Server لكن كل واحد له Schema أوLogical Namespace منفصلة.
ده يعمل Structural Boundary أقوى من Shared Tables بدون Dedicated Server لكل Tenant.
لكن Provisioning وMigrations وTooling لازم تتعامل مع Schemas كثيرة بدل واحدة.
3. Database per Workspace
كل Workspace لها Database.
Workspace A → Database A
Workspace B → Database B
Workspace C → Database C
Isolation أسهل في التفكير لأن Business Data للعملاء مش موجودة في نفس Database Namespace.
لكن Operational Problem تتغير تمامًا.
أنت مش بتدير “Database”.
أنت بتدير Fleet of Databases.
وده فرق مهم.
ليه Teams تفكر في Database-per-Workspace؟
أقوى سبب عادة Isolation، مش Performance.
لما Customer A وB في Databases مختلفة، أنواع كثيرة من Accidental Cross-tenant Queries تصبح أصعب Structurally.
وده ممكن يسهل Tenant-specific Backup وRestore وExport وDeletion.
Enterprise Customers ممكن كمان يكون عندهم Retention أوRegional أوOperational Requirements مختلفة.
لكن Stronger Isolation لها تكلفة في Provisioning وMigrations وConnections وObservability وFleet Operations.
Isolation مش معناها Security تلقائيًا
Separate Database مش معناها SaaS Secure by Default.
Application ممكن تتصل بـWrong Database. Queue Job تحمل Wrong Workspace Context. Cache Key تنسى Tenant ID. Object Storage Path تكشف File. Admin Tool تتجاوز Boundary.
Database Isolation Layer of Defense، مش Security Model كاملة.
Workspace Context لازم تكون Explicit خلال Request وJob Lifecycle.
Shared Tables مش Unsafe تلقائيًا
العكس برضه غلط.
Shared-table System مصممة كويس ممكن تفرض Tenant Scoping عن طريق Application Architecture وDatabase Policies عند الحاجة وAutomated Tests وAccess Patterns واضحة.
لمنتجات SaaS كثيرة، ده أبسط Architecture تحقق المطلوب.
ما تختارش Database-per-Workspace علشان شكلها “Enterprise”. اختارها لو Properties بتاعتها تحل Requirement حقيقية.
Hidden Cost: Provisioning
في Shared DB، Onboarding Workspace جديدة ممكن يكون Application Data فقط.
مع Database-per-Workspace، Onboarding تتحول Infrastructure Orchestration:
- Create/allocate Database.
- Apply Current Schema.
- Create Credentials/Access Policy.
- Register Connection.
- Seed Required Data.
- Verify Health.
- Mark Workspace Ready بعد Success فقط.
Process لازم تكون Idempotent.
لو Step فشلت، Retry ما تعملش Database ثانية أوHalf-provisioned Tenant مجهولة.
Provisioning أصبحت جزء من Product Architecture.
Migrations تصبح Distributed Operation
في Shared DB، Migration تعمل مرة.
مع مئات أو آلاف Workspace Databases، نفس Logical Migration تتكرر مئات أو آلاف المرات.
اسأل: هل Migration Safe للRetry؟ ماذا لو 97% نجح والباقي فشل؟ هل App تتحمل Mixed Schema Versions مؤقتًا؟ تعرف مين Behind؟ تقدر توقف Bad Rollout بسرعة؟
Migration Command وحدها مش كفاية.
تحتاج Migration Orchestration وMigration State.
ما تفترضش إن كل Tenant على نفس Schema Version
في Fleet Scale، Partial Failure طبيعي.
Track Schema State لكل Workspace:
Target: 142
Workspace A: 142 ✓
Workspace B: 142 ✓
Workspace C: 141 !
Workspace D: migration failed
الرؤية دي أفضل من افتراض إن Deployment نجحت لأن Process انتهت.
Backups مكان مهم لقيمة Isolation
Database-per-Workspace تخلي Tenant-level Backup/Restore واضحة Conceptually.
لو Customer يحتاج Recovery، ممكن تسترجع Database بتاعته بدون Restoring بيانات كل العملاء.
لكن لازم تحدد Backup Frequency، Retention، Encryption، Restore Testing، PITR، Storage، Credentials وSafe Reattachment.
Backup لم تختبر Restore لها هي مجرد Theory.
حذف Workspace أوضح — وأخطر
Physical Boundary قوية ممكن تسهل Deletion: حدد Tenant Database واحذفها حسب Retention Policy.
لكن Wrong Database Identifier في Destructive Operation كارثة.
تحتاج Strong Identity Checks وAudit Logs وDelayed Deletion عند الحاجة وRecovery Policy واضحة.
Connection Management ممكن تصبح Bottleneck الحقيقية
Traditional App عندها Pool لاتصالات مع عدد صغير من Databases.
Database-per-Workspace تعمل Connection Topology أكبر بكثير.
Dedicated Pool لكل Tenant ممكن تستهلك Resources قبل ما Query Throughput تكون المشكلة.
قد تحتاج Dynamic Connection Resolution وBounded Pools وConnection Proxy حسب Platform وWorkload.
مهم جدًا لو Tenants كثيرة لكن Activity لكل Tenant قليلة.
ما تعملش Capacity Planning على Queries/sec فقط. احسب Active Connection Behavior.
Tenant Context لازم تعيش داخل Queues
Web Request تعرف Workspace من Domain أوSession أوToken أوRoute.
Background Job مش عندها Request Context تلقائيًا.
أي Job لReport أوNotification أوIntegration لازم تحمل Workspace Identity وتعمل Resolve للDatabase الصحيحة.
Job Payload
workspace_id
task data
↓
Workspace Resolver
↓
Correct DB Connection
↓
Domain Operation
ما تعتمدش على Connection كانت Active في Worker قبلها، خصوصًا Long-running Workers.
Cache جزء من Multi-Tenancy
لو Workspace A وB عندهم Record ID 42، Key مثل:
property:42
مش Tenant-safe.
لازم Boundary:
workspace:abc:property:42
نفس الكلام Locks وRate Limits وSessions وComputed Reports وTemporary Data.
Database Isolation مش بتحمي Shared Redis Namespace تلقائيًا.
Files وObject Storage تحتاج نفس Boundary
استخدم Tenant-aware Paths مثل:
workspaces/{workspace_id}/documents/{document_id}
وAuthorization حقيقية. Unguessable URL مش Authorization Mechanism.
Search ممكن ترجع مشكلة Isolation من جديد
ممكن Product تستخدم Separate Databases لكن Shared Search Index.
ساعتها Search Layer مكان جديد لازم Tenant Filtering تكون صحيحة فيه.
ونفس الكلام Vector Databases وRAG.
لو AI Retrieval تبحث في Knowledge للعملاء، Workspace Isolation لازم تتفرض قبل أو أثناء Retrieval، مش Prompt تقول “استخدم بيانات العميل ده فقط”.
Prompt مش Security Boundary.
Analytics أسهل مع Shared Data
Shared Database تسهل Cross-tenant Internal Analytics.
Database-per-Workspace تفرق Data.
لو Business تحتاج Platform-wide Metrics، اعمل Analytics Pipeline تجمع Approved Events/Aggregates في Analytics Store.
ما تخليش Dashboard تعمل Loop Real-time على كل Production Tenant DB.
Operational وAnalytical Workloads احتياجاتهم مختلفة.
Reporting يحتاج Strategy واضحة
Tenant Report سهلة: Query Database بتاعته.
Platform-wide Report مش سهلة.
حدد مبكرًا Tenant-local Reports، Operational Metrics، Financial Aggregates وProduct Analytics، واعمل Data Path مناسبة لكل نوع.
Observability لازم تعرف Workspace
Log مثل SQL timeout مش كفاية.
Telemetry لازم تحدد Workspace بشكل آمن، Database/Cluster، App Version، Schema Version، Correlation ID وError Context.
ده يخليك تعرف المشكلة Tenant واحدة ولا Group ولا Platform كلها، بدون تسريب Sensitive Data للLogs.
Cost مش Storage فقط
Database-per-Workspace ممكن تضيف Cost من Minimum Allocations، Connections/Proxies، Backups، Monitoring، Provisioning Systems، Migration Orchestration، Support وAnalytics Pipelines.
Shared Database قد تكون أرخص وأبسط، خصوصًا في بداية Product.
قارن Total Operating Complexity and Cost، مش Price/GB فقط.
Database لكل Workspace لا تعني Server لكل Workspace
Logical Database لكل Customer مش لازم Dedicated Physical Server لكل Customer.
Databases كثيرة ممكن تشترك في Managed Cluster حسب Platform ومتطلبات Isolation.
المهم Logical Isolation Boundary وطريقة Resource Allocation تحتها.
Hybrid Model تستحق التفكير
مش لازم الاختيار يكون واحد لكل العملاء للأبد.
SaaS ممكن تستخدم Shared Infrastructure للعملاء العاديين وDedicated DB/Cluster لبعض Enterprise أوRegulated Customers.
أو Sharding: مجموعة Workspaces لكل Database بدل Global DB واحدة.
Hybrid تزود Routing Complexity لكنها تخلي Infrastructure تناسب Requirement بدل دفع أعلى Isolation لكل Tenant.
فكر في Tenant Movement قبل ما تحتاجه
لو Customer بدأت Shared وبعدها احتاجت Dedicated، تقدر تنقلها؟ لو Cluster امتلأت، تقدر Rebalance؟
افصل Tenant Identity عن Physical Connection Location.
بدل Hard-coded Mapping، استخدم:
workspace_id → placement → connection/configuration
ده يفتح باب Rebalancing وEnterprise Upgrades.
Data Residency ممكن تغير Topology
بعض المنتجات تحتاج Customer Data في Region معينة.
Tenant Placement Layer تساعد، لكن Residency أكبر من Primary Database: Backups وFiles وSearch وLogs وAnalytics وThird-party Integrations ممكن تحمل Data.
ما تقولش Region-isolated لأن PostgreSQL فقط اتحركت.
Laravel: Central DB + Tenant Connections
Conceptual Design شائعة:
Central DB
- workspaces
- users / memberships
- subscriptions
- tenant placement
- platform configuration
وبعدين Tenant Business Data خلف Workspace-resolved Connection.
Middleware تعمل Context للHTTP، وQueue Middleware/Job Bootstrap تعمل نفس الشيء للBackground Work.
Domain Code ما تخترعش Connection Names في كل مكان. Centralize Tenant Resolution علشان تتTest وتتAudit.
Go: خلي Tenant Dependencies Explicit
في Go، Handler أوWorker تعمل Resolve للWorkspace، تحصل على Data-store Handle الصحيحة، ثم تمرر Tenant-scoped Repository/Service للUse Case.
ده يقلل Global Mutable Connection State.
المبدأ:
Tenant Identity لازم تكون Explicit Dependency لأي Tenant Work.
Testing لازم يكون Adversarial
اختبر مش Happy Path فقط:
- هل Workspace A تقدر تطلب Record لـB؟
- Queue Job ممكن تعمل Resolve للTenant الغلط؟
- Cache Value ممكن تعبر Boundary؟
- Search ترجع Document من Tenant ثانية؟
- Admin Endpoint تنسى Scoping؟
- ماذا يحدث مع Incomplete Provisioning؟
Multi-tenant Bugs غالبًا Software Bugs عادية بعواقب أكبر.
إمتى Shared Tables غالبًا أفضل؟
لما Product في البداية، Requirements تتغير، Data Volumes modest، Cross-tenant Analytics مهمة، مفيش Strong Isolation Requirement، والTeam تريد أبسط Operational Model.
البساطة لها قيمة.
ما تدفعش Distributed-operations Complexity قبل ما Product تحتاجها.
إمتى Database-per-Workspace تصبح أقوى؟
لما Strong Tenant Isolation Requirement أساسية، Tenant-level Backup/Restore/Export مهمة، Customers يحتاجوا Placement Policies مختلفة، Tenant واحدة ممكن تكبر بشكل مستقل، والEngineering Team جاهزة تعمل Automation لـDatabase Fleet Operations.
النقطة الأخيرة أهم واحدة.
لو Provisioning وMigrations وMonitoring وRecovery Manual، Architecture دي ممكن تتحول Operational Trap.
Decision Framework
قبل الاختيار جاوب:
- أنهي Isolation محتاجها Product فعلًا؟
- كام Tenant متوقع وكام واحدة Active في نفس الوقت؟
- Tenant واحدة ممكن تكبر قد إيه؟
- هل تحتاج Tenant-level Backup/Restore؟
- هل Customers تحتاج Region/Infrastructure Choices؟
- Cross-tenant Analytics مهمة قد إيه؟
- Deployment System تقدر تعمل Migrations لكثير من Databases بأمان؟
- Workers هتعمل Resolve للTenant إزاي؟
- هتراقب Schema Version وHealth لكل Tenant إزاي؟
- Total Operational Cost للTopology إيه؟
- تقدر تنقل Tenants بين Placements بعدين؟
- Cache/Files/Search/AI Retrieval هتفرض نفس Boundary إزاي؟
الإجابات دي أهم من Copy Architecture من SaaS ثانية.
الـArchitecture الحقيقية هي Lifecycle
Create Database هو الجزء السهل.
التصميم الحقيقي:
Provision
→ Migrate
→ Connect
→ Observe
→ Back up
→ Restore
→ Upgrade
→ Move
→ Suspend
→ Delete
لو اخترت Database-per-Workspace، صمم Lifecycle قبل Tenant Count ما تخلي Manual Operations مستحيلة.
ولو اخترت Shared Tables، صمم واختبر Tenant Scoping قبل Codebase ما تخلي Unscoped Access طبيعي.
Multi-Tenancy مش Database Feature؛ هي Application-wide Isolation Model.
Database Topology تدعم Model دي، مش تحملها وحدها.
بتصمم SaaS ومحتار بين Shared Multi-Tenancy وDatabase-per-Workspace أوHybrid Architecture؟
أساعد Teams في تصميم SaaS Architecture من Tenancy وData Boundaries إلى APIs وQueues وDeployment وObservability وProduction Scaling، بحيث Isolation Model تناسب Business بدل ما تتحول Rewrite مكلفة بعدين.
مرتبط: SaaS Development، SaaS vs Custom Software، Engineering Architecture وBuilding a Private RAG Stack on PostgreSQL.
التعليقات (0)