تصميم معمارية SaaS متعددة المستأجرين: من 100 إلى 10,000 عميل دون تسريب للبيانات
مقارنة معمارية شاملة بين نماذج عزل قواعد البيانات والمخططات وقواعد البيانات المشتركة مع تأمين حقول المستأجر وإدارة الهجرات البرمجية.
🏢 Multi-Tenancy — Designing a SaaS for 100 → 10,000 Tenants
نسخة واحدة من التطبيق، آلاف العملاء،
وكل Tenant يشوف بياناته فقط.
📚 المحتويات
- سؤال الانترفيو
- يعني إيه Multi-Tenancy؟
- المشكلة في نسخة لكل Customer
- اختيار Data Isolation Strategy
- 1. Database Per Tenant
- 2. Shared Database + TenantId
- 3. Schema Per Tenant
- مقارنة سريعة
- Tenant Resolution
- JWT و TenantId
- Subdomain و Custom Domain
- Authorization vs Tenant Isolation
- Global Query Filters
- Database Indexing
- Composite Indexes
- Unique Constraints
- Caching
- Background Jobs
- File Storage
- Logs و Observability
- Noisy Neighbor
- Partitioning
- Sharding
- Hybrid / Tiered Tenancy
- Tenant Catalog
- Migrations
- Backups و Restore
- Security
- اختيار Architecture عملي
- إجابة انترفيو جاهزة
- الخلاصة
- مصادر رسمية
🎯 سؤال الانترفيو
مبروك.
أنت عملت نظام إدارة جيم.
النظام نجح.
وبدأت جيمات تانية تطلب استخدامه.
بعد فترة بقى عندك:
100 Gym
500 Gym
1000 Gym
10000 Gym
لكن كل Gym لازم يشوف:
بياناته فقط
ولا يمكن:
Gold Gym
تشوف بيانات:
Power Gym
إزاي تصمم النظام؟
❌ الحل الساذج: نسخة لكل Customer
ممكن تعمل:
Gold Gym App
Power Gym App
Fit Zone App
وكل واحد له:
Application
Database
Deployment
في البداية يبدو ممتازًا.
لكن عند:
1000 Tenants
تبدأ الكارثة.
Bug واحد:
Fix × 1000
Feature جديدة:
Deploy × 1000
Migration:
Run × 1000
Monitoring:
1000 systems
Backup:
1000 databases
وده مش مجرد مشكلة تقنية.
دي مشكلة:
Operational Complexity
🏢 يعني إيه Multi-Tenancy؟
Multi-Tenancy يعني:
Application واحد يخدم أكثر من Customer مع وجود عزل منطقي أو فعلي لبيانات كل Customer.
كل Customer يسمى:
Tenant
مثلاً:
Gold Gym
Power Gym
Fit Zone
كلهم يستخدموا نفس النظام.
لكن:
Tenant A
↓
Data A
Tenant B
↓
Data B
Tenant C
↓
Data C
الهدف:
Shared Application
+
Tenant Isolation
🧩 أهم سؤال: هتعزل البيانات إزاي؟
عندك أكثر من Strategy.
أشهرهم:
Database Per Tenant
Shared Database + TenantId
Schema Per Tenant
وممكن تعمل Hybrid بين أكثر من Strategy.
Microsoft نفسها توضح أن Multi-Tenancy لها عدة نماذج، وأن الاختيار يعتمد على isolation والـ cost والـ operational requirements. citeturn0search1turn0search2turn0search5
1️⃣ Database Per Tenant
كل Tenant له Database مستقلة.
GoldGym_DB
PowerGym_DB
FitZone_DB
والـ Application نفسه ممكن يكون Shared.
┌───────────────┐
Tenant A ───────►│ │
Tenant B ───────►│ Shared App │
Tenant C ───────►│ │
└───────┬───────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
DB-A DB-B DB-C
✅ المميزات
Isolation قوي
لو Query فيها bug:
SELECT *
FROM Members;
فأنت أصلاً متصل بقاعدة Tenant معينة.
وده يقلل خطر cross-tenant access مقارنةً بنموذج shared tables.
Backup مستقل
تقدر تعمل:
Backup Tenant A
Restore Tenant A
بدون التأثير المباشر على باقي العملاء.
Performance Isolation
Tenant ضخم ممكن ياخد:
Dedicated Database
بدون ما يشارك نفس Database resources مع باقي العملاء.
Migration / Export
ممكن يكون أسهل في بعض سيناريوهات نقل Tenant بالكامل.
❌ العيوب
لو عندك:
1000 Tenants
يبقى:
1000 Databases
وده يرفع:
Provisioning Cost
Monitoring Complexity
Backup Complexity
Migration Complexity
Connection Management
Operational Overhead
ولو عندك Migration:
Add column
لازم تدير تطبيقها على كل قواعد البيانات.
Microsoft تشير إلى أن database-per-tenant يمكن أن يكون مناسبًا، لكن إدارة عدد كبير من قواعد البيانات تحتاج automation وإدارة deployment قوية. citeturn0search6turn0search2
📊 مشكلة Reporting
لو كل Tenant في Database:
DB A
DB B
DB C
...
DB N
وعايز:
Total Revenue Across All Tenants
مش هتعمل:
SELECT SUM(amount)
FROM Payments;
لأن البيانات موزعة.
هتحتاج:
Cross-database aggregation
Data warehouse
ETL/ELT
Analytics pipeline
Federated querying
حسب حجم النظام.
وده يزود التعقيد.
🥇 2. Shared Database + TenantId
ده من أبسط وأشهر النماذج.
كل العملاء في:
Same Database
Same Tables
لكن كل Business Record فيها:
TenantId
مثلاً:
Members
Id | Name | TenantId
---|-------|---------
1 | Ahmed | 1
2 | Omar | 1
3 | Sara | 2
Payments:
Id | Amount | TenantId
---|--------|---------
1 | 500 | 1
2 | 700 | 2
Subscriptions:
Id | TenantId
---|---------
1 | 1
2 | 2
بالتالي:
TenantId = 1
يعني:
Gold Gym
⭐ ليه النموذج ده جذاب؟
لأنك عندك:
1 Application
1 Database
1 Schema
1 Migration Pipeline
1 Backup Strategy
1 Monitoring Stack
بدل:
1000 Applications
1000 Databases
1000 Deployments
وده غالبًا يقلل الـ operational overhead بشكل كبير.
Azure Architecture Center يذكر أن shared multitenant infrastructure عادةً يعطي أعلى كثافة للعملاء وأقل تكلفة وإدارة مقارنةً بنماذج العزل الأعلى، مع ضرورة الانتباه إلى scale limits وtenant isolation. citeturn0search2
🚨 لكن هنا تبدأ المشكلة الخطيرة
أنت الآن تعتمد على:
TenantId
عشان تمنع:
Tenant A → Tenant B Data
فلو Developer كتب:
SELECT *
FROM Members;
بدون:
WHERE TenantId = @TenantId
فأنت عندك:
Data Isolation Bug
وده ممكن يتحول إلى:
Security Incident
🔐 Tenant Isolation لازم تكون Defense in Depth
ما تعتمدش على:
Developer remembering WHERE TenantId = ...
فقط.
ممكن تعمل طبقات:
Authentication
↓
Tenant Resolution
↓
Authorization
↓
Application-level filtering
↓
ORM Global Query Filter
↓
Database-level protection
حسب الـ DBMS والـ architecture.
في Azure SQL مثلًا، Microsoft توضح أن Row-Level Security يمكن استخدامه للمساعدة في فرض tenant-level isolation داخل shared tables. citeturn0search4
🧭 Tenant Resolution
أول سؤال في أي Request:
الـ Request ده تابع لأنهي Tenant؟
مثلاً:
GET /members
مين اللي بيحدد Tenant؟
عندك طرق متعددة.
1️⃣ Subdomain
مثلاً:
goldgym.example.com
النظام يقرأ:
goldgym
ويعمل mapping:
goldgym → TenantId 1
مناسب جدًا لو عايز تجربة SaaS واضحة.
2️⃣ Custom Domain
مثلاً:
app.goldgym.com
أو:
portal.goldgym.com
الـ platform تعمل mapping للـ hostname إلى Tenant.
هنا تحتاج:
Domain Verification
Tenant Mapping
TLS
DNS Management
3️⃣ JWT Claim
بعد Login:
{
"sub": "user-15",
"tenantId": "tenant-3",
"role": "Admin"
}
كل Request بعدها يحمل identity وtenant context.
لكن مهم جدًا:
وجود tenantId في JWT لا يعني تلقائيًا أن المستخدم مسموح له بكل شيء داخل الـ Tenant.
لازم تفرق بين:
Who is the user?
و:
Which tenant is the user operating in?
و:
What is the user allowed to do?
4️⃣ API Key
في B2B systems ممكن يكون عندك:
API Key → Tenant
لكن لازم يكون عندك secure key management وrotation وrevocation.
⚠️ لا تثق في TenantId المرسل من الـ Client
خطأ خطير:
GET /members?tenantId=2
وتقول:
خلاص المستخدم Tenant 2.
لأن المستخدم ممكن يغيرها إلى:
?tenantId=3
الأفضل أن Tenant context يأتي من:
Authenticated Identity
Trusted Hostname Mapping
Server-side Tenant Resolution
ثم تتحقق من authorization.
🔒 Authorization vs Tenant Isolation
دي نقطة مهمة جدًا.
عندك:
User
Tenant
Role
Resource
مثلاً:
User: Ahmed
Tenant: Gold Gym
Role: Manager
مش معنى إن أحمد داخل Gold Gym إنه يقدر يعمل:
Delete Everything
إذن عندك مستويين على الأقل:
Tenant Isolation
+
Authorization
مثال:
Is this resource owned by my tenant?
+
Am I allowed to perform this action?
🧱 Global Query Filters
لو بتستخدم EF Core، تقدر تعمل Global Query Filter.
بدل:
var members = db.Members
.Where(x => x.TenantId == tenantId)
.ToList();
في كل مكان.
تقدر تعرف filter مركزي:
modelBuilder.Entity<Member>()
.HasQueryFilter(x => x.TenantId == tenantId);
فتصبح queries العادية:
db.Members.ToList();
ويتم تطبيق tenant filter تلقائيًا.
Microsoft توثق Global Query Filters كاستخدام مباشر للـ multi-tenancy، وتوضح أنها تضيف filter تلقائيًا على queries للـ entity. citeturn0search0
⚠️ لكن Global Query Filter مش Magic Security Boundary
لازم تنتبه.
بعض APIs/queries تقدر تتجاوز filters.
وكمان:
Raw SQL
Stored Procedures
Reports
Background Jobs
Admin Queries
ETL
ممكن تخرج خارج الـ ORM abstraction.
لذلك:
Global Query Filter طبقة حماية مهمة، لكنها لا تعفيك من تصميم tenant isolation بشكل شامل.
ولو security requirement عالية، فكر في database-level enforcement مثل Row-Level Security حيث تكون مدعومة.
📈 Indexing
لو عندك:
50 Million Members
وأغلب queries:
SELECT *
FROM Members
WHERE TenantId = @TenantId;
لازم تفكر في indexing.
مثلاً:
CREATE INDEX IX_Members_TenantId
ON Members(TenantId);
لكن غالبًا الـ real index design لازم يتبني على الـ actual query patterns.
🧩 Composite Index
مثلاً:
SELECT *
FROM Members
WHERE TenantId = @TenantId
AND Email = @Email;
ممكن يكون عندك:
(TenantId, Email)
مثلاً:
CREATE UNIQUE INDEX UX_Members_Tenant_Email
ON Members(TenantId, Email);
وده يعمل حاجتين:
Fast lookup
+
Tenant-scoped uniqueness
🔑 Unique Constraints
دي نقطة ناس كتير بتنسى فيها TenantId.
لو عملت:
UNIQUE(Email)
فـ:
Ahmed@gmail.com
مينفعش يظهر إلا مرة واحدة في كل النظام.
لكن في SaaS ممكن يكون الطبيعي:
Gold Gym → Ahmed@gmail.com
Power Gym → Ahmed@gmail.com
عشان كده حسب الـ business rule ممكن تحتاج:
UNIQUE(TenantId, Email)
لكن مش كل uniqueness لازم تكون Tenant-scoped.
مثلاً:
Global domain
Global tenant slug
Global external identifier
قد تكون global فعلًا.
المهم:
حدد الـ business invariant قبل ما تعمل constraint.
🗃️ Tenant-First Indexing
في Shared Database، كثير من queries تبدأ بـ:
TenantId
لذلك index design غالبًا يحتاج tenant-aware patterns مثل:
(TenantId, CreatedAt)
(TenantId, Email)
(TenantId, Status)
(TenantId, MemberId)
لكن لا تعمل indexes عشوائيًا على كل combination.
اعتمد على:
Query Patterns
Selectivity
Write Cost
Index Size
Execution Plans
⚡ Caching
هنا غلطة خطيرة جدًا.
لو عملت:
member:15
ممكن Tenant A يخزن:
member:15 → Ahmed
وبعدها يحصل collision أو reuse غير صحيح مع Tenant آخر.
الأفضل يكون الـ key tenant-aware:
tenant:1:member:15
أو:
tenant:{tenantId}:member:{memberId}
ونفس الفكرة في:
Redis
Application Cache
CDN Cache
HTTP Cache
Search Index
🔥 Cache Isolation
مش بس:
Cache Key
لازم تفكر كمان في:
Cache Invalidation
Cache TTL
Authorization
Private vs Public data
خصوصًا لو response نفسه tenant-specific.
مثلاً:
GET /dashboard
مينفعش CDN تعتبر response واحد صالح لكل tenants إلا لو المحتوى فعلاً public/shared.
📨 Background Jobs
دي من أخطر الأماكن.
أنت أثناء HTTP request عندك:
TenantId = 15
لكن Job هتشتغل بعد:
1 minute
1 hour
1 day
فمين قال للـ worker:
"أنا تابع لـ Tenant 15"؟
لازم tenant context يكون جزءًا من job payload أو يكون قابلًا للاسترجاع بشكل موثوق.
مثلاً:
{
"jobId": "job-123",
"tenantId": "tenant-15",
"type": "GenerateInvoices"
}
ثم:
Worker
↓
Resolve Tenant
↓
Load Tenant Context
↓
Execute scoped operation
📁 Files
لو عندك:
Profile Pictures
Invoices
Documents
Reports
لا تجمع كل شيء بدون naming/isolation strategy.
مثلاً:
/tenant-1/profile/...
/tenant-1/invoices/...
/tenant-2/profile/...
/tenant-2/invoices/...
أو bucket/container strategy مناسبة.
والأهم:
Path naming وحده مش Authorization.
لو الملف private:
User requests file
↓
Authenticate
↓
Resolve Tenant
↓
Authorize
↓
Generate signed URL
🧾 Logs
لو عندك:
1000 Tenants
والعميل قال:
"عندي Error."
لازم تقدر تبحث:
tenantId
userId
requestId
traceId
service
timestamp
مثلاً:
tenantId=42
userId=900
requestId=req_123
traceId=abc...
ده يسهل:
Debugging
Monitoring
Auditing
Incident Response
📡 Observability
في Multi-Tenant SaaS، metrics نفسها لازم تفكر فيها tenant-aware.
مثلاً:
requests per tenant
errors per tenant
latency per tenant
storage per tenant
jobs per tenant
API usage per tenant
ده يساعدك تكتشف:
Noisy Neighbor
Abuse
Tenant-specific bugs
Unexpected growth
Cost drivers
📢 Noisy Neighbor
تخيل:
Tenant A → 1,000 users
Tenant B → 10 users
Tenant A
↓
Huge report
↓
Millions of rows
↓
CPU 100%
↓
Connections exhausted
وباقي العملاء:
Tenant B
Tenant C
Tenant D
...
يحسوا إن السيستم كله بقى بطيء.
ده:
Noisy Neighbor Problem
Azure يوضح أن مشاركة الموارد قد تؤدي إلى أن Tenant صاحب الاستخدام العالي يؤثر على أداء باقي العملاء، ولذلك يمكن استخدام deployments أو databases منفصلة لبعض العملاء عند الحاجة لعزل الأداء. citeturn0search5turn0search2
🛡️ حلول Noisy Neighbor
ممكن تستخدم:
Rate Limiting
Quota
Per-tenant concurrency limits
Job queues
Workload isolation
Database per tenant
Shard per tenant/group
Dedicated deployment
وممكن تعمل:
Standard Tenants
↓
Shared Infrastructure
Enterprise Tenant
↓
Dedicated Database
وده يسمى أحيانًا:
Hybrid / Tiered Tenancy
🧩 Hybrid Multi-Tenancy
مش لازم تختار strategy واحدة لكل العملاء.
مثلاً:
950 Tenants
↓
Shared Database
40 Large Tenants
↓
Dedicated Database
10 Enterprise Tenants
↓
Dedicated Deployment + Database
وده ممكن يكون أفضل بكثير من محاولة فرض نفس isolation model على الجميع.
Azure Architecture Center يذكر صراحة إمكانية استخدام multitenant database لمعظم العملاء مع single-tenant stamps للعملاء الذين لديهم احتياجات أو متطلبات غير عادية. citeturn0search2turn0search5
🗂️ Partitioning
لو Shared Database كبرت جدًا:
50M
100M
500M rows
ممكن تبدأ تفكر في:
Partitioning
الفكرة:
بدل table واحدة ضخمة منطقيًا:
Members
تتقسم إلى partitions حسب strategy مناسبة.
ممكن تكون حسب:
Tenant range
CreatedAt
Region
Hash
لكن:
Partitioning مش معناها تلقائيًا إن الـ DB هتبحث فقط في Tenant partition.
لازم الـ partition key/query predicates يسمحوا بـ:
Partition Pruning
وإلا قد لا تحصل على الفائدة المتوقعة.
🧱 Sharding
لو Database واحدة لم تعد كافية:
DB1
DB2
DB3
DB4
مثلاً:
Tenant 1 → DB1
Tenant 2 → DB1
Tenant 1001 → DB2
Tenant 2001 → DB3
ده:
Sharding
والـ application أو shard map يعرف:
Tenant → Shard
Microsoft توضح أن shard maps يمكن استخدامها لربط tenant keys بالـ shards، مع trade-off بين التكلفة والعزل. citeturn0search12
🧭 Tenant Catalog
لو عندك أكثر من database/shard، محتاج تعرف:
TenantId
Tenant Name
Status
Plan
Region
Database / Shard
Connection information reference
Deployment Stamp
مثلاً:
Tenants
Id | Name | Plan | Shard
---|-----------|------------|------
1 | Gold Gym | Standard | shard-1
2 | Power Gym | Enterprise | db-17
3 | Fit Zone | Standard | shard-1
ده يسمى غالبًا:
Tenant Catalog
وهو مصدر مركزي يساعد النظام يعرف:
Tenant ده موجود فين؟
🏗️ Schema Per Tenant
حل وسط.
Database واحدة:
GymDB
لكن كل Tenant له schema:
goldgym.Members
goldgym.Payments
powergym.Members
powergym.Payments
هنا الـ schema نفسها تحدد ownership.
✅ المميزات
عزل منطقي أقوى من مجرد:
TenantId
وتنظيم البيانات واضح.
ممكن تكون عندك permissions على مستوى schemas حسب الـ DBMS.
PostgreSQL مثلًا يدعم schemas كمساحات أسماء تحتوي tables ويمكن التحكم في privileges عليها. citeturn0search7
❌ العيوب
لو:
1000 Tenants
و:
50 Tables
فأنت ممكن توصل إلى:
1000 × 50
=
50,000 tables
تقريبًا.
Migration:
Apply × 1000
Index:
Create × 1000
Monitoring:
More objects
Reporting:
Cross-schema aggregation
كلها تصبح أكثر تعقيدًا.
⚠️ نقطة مهمة جدًا عن EF Core
لو بتستخدم EF Core:
Microsoft توضح أن:
TenantId + Global Query Filter
مدعوم مباشرة.
أما:
Schema Per Tenant
فهو ليس مدعومًا كـ multi-tenancy approach مباشر في EF Core، وتصف Microsoft هذا النموذج بأنه غير موصى به عند استخدام EF Core migrations بالطريقة المعتادة. citeturn0search1
فلو مشروعك:
.NET + EF Core
فده سبب إضافي إن:
Shared Tables + TenantId
غالبًا أبسط.
🧠 Database Per Tenant vs Shared DB
| النقطة | Shared + TenantId | Database Per Tenant |
|---|---|---|
| Cost | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Operational simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Data isolation | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Per-tenant backup | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Cross-tenant reporting | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Noisy neighbor isolation | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Scaling huge tenants | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Migrations | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Tenant-specific customization | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Number of DB objects | منخفض | مرتفع |
| Automation requirement | متوسط | مرتفع |
التقييم تقريبي، وليس قاعدة عامة. Architecture الصحيحة تعتمد على requirements والـ DBMS والـ workload.
🎯 إيه الاختيار العملي؟
لو بتبني SaaS جديد وعندك:
10
100
1000
Tenant، ومفيش requirements خاصة جدًا:
ابدأ غالبًا بـ:
Shared Application
+
Shared Database
+
TenantId
+
Tenant Resolution
+
Authorization
+
Global Query Filters
+
Tenant-aware Indexes
وده تصميم بسيط وقابل للنمو لو الـ schema والـ indexes والـ queries مصممة صح.
🏆 وبعدها لما يكبر النظام
ممكن تتحرك تدريجيًا:
Stage 1
Shared DB
↓
TenantId
Stage 2
Shared DB
↓
Partitioning / Better Indexes
Stage 3
Sharding
↓
Tenant Groups
Stage 4
Large Tenant
↓
Dedicated DB
Stage 5
Enterprise Tenant
↓
Dedicated Stamp / Deployment
مش لازم تعمل:
Database Per Tenant
من أول يوم.
🏢 Hybrid Architecture عملية جدًا
مثال:
┌──────────────────┐
│ Shared App │
└────────┬─────────┘
│
┌──────────┴──────────┐
│ Tenant Catalog │
└──────────┬──────────┘
│
┌───────────────┼────────────────┐
▼ ▼ ▼
Shared DB Shard DB Dedicated DB
900 tenants 90 tenants 10 enterprise
وده يخليك تستخدم:
Density
+
Isolation
+
Scalability
في نفس الوقت.
🔐 Security Checklist
قبل ما تقول:
"خلصنا Multi-Tenancy."
راجع:
[ ] Tenant Resolution
[ ] Tenant Authorization
[ ] TenantId on business data
[ ] Global Query Filters
[ ] Raw SQL reviewed
[ ] Admin queries scoped
[ ] Background jobs carry tenant context
[ ] Cache keys include tenant scope
[ ] File paths/storage are tenant-aware
[ ] Search indexes are tenant-aware
[ ] Unique constraints are tenant-aware where required
[ ] Logs contain tenant context
[ ] Metrics can be segmented by tenant
[ ] Rate limits / quotas exist
[ ] Noisy neighbors are controlled
[ ] Tenant-aware backups/restore strategy
[ ] Migration automation
[ ] Cross-tenant reporting is intentional
🚨 أكبر الأخطاء
❌ 1. TenantId موجود لكن مش مستخدم
Column exists
Security doesn't.
❌ 2. Trusting client TenantId
?tenantId=999
والسيرفر يصدق.
❌ 3. Cache key بدون tenant
member:15
بدل:
tenant:42:member:15
❌ 4. Background job بدون Tenant Context
GenerateInvoice(jobId)
بدل:
GenerateInvoice(tenantId, jobId)
❌ 5. Raw SQL خارج الـ tenant boundary
SELECT *
FROM Members;
بدون tenant restriction أو database-level isolation.
❌ 6. Tenant-scoped uniqueness غلط
UNIQUE(Email)
رغم إن الـ business يسمح بنفس email في أكثر من Tenant.
❌ 7. تجاهل Noisy Neighbor
Tenant واحد يعمل:
Huge Report
ويوقع performance للجميع.
🧠 إجابة انترفيو جاهزة
لو الـ interviewer سألك:
"عندي SaaS يخدم 1000 Gym، وكل Gym لازم يشوف بياناته فقط. هتصمم إزاي؟"
ممكن تجاوب:
"هبدأ غالبًا بـ shared application وshared database، وأضيف
TenantIdلكل business table. أول خطوة في كل request هي tenant resolution من authenticated identity أو subdomain/custom domain، وبعدها authorization للتأكد إن المستخدم تابع للـ tenant ومسموح له بالعملية."
ثم:
"على مستوى data access هستخدم tenant-aware repositories أو global query filters، ومش هعتمد فقط على إن developer يفتكر يضيف
WHERE TenantId. كمان هصمم indexes وunique constraints بناءً على tenant-scoped query patterns."
ثم:
"هخلي الـ cache keys والـ background jobs والـ files والـ logs والـ search indexes tenant-aware، وأضيف rate limits وquotas عشان أمنع noisy neighbors."
ثم:
"لو Tenant معين كبر جدًا أو عنده requirements خاصة للعزل أو performance، مش لازم أنقل النظام كله. ممكن أعمل hybrid model: معظم العملاء shared، والعملاء الكبار dedicated database أو deployment."
ثم:
"لو الحجم كبر جدًا، أقدر أضيف partitioning أو sharding حسب الـ workload. القرار النهائي يعتمد على isolation requirements، cost، performance، compliance، operational complexity، وطبيعة الـ queries."
🧠 السؤال الأصعب
لو interviewer قال:
"طب ليه مش Database Per Tenant وخلاص؟"
جاوبه:
"لأن isolation مش المعيار الوحيد. Database-per-tenant يعطي isolation أعلى، لكنه يرفع operational complexity: provisioning، migrations، monitoring، backups، connection management، وcross-tenant analytics. لو عندي آلاف العملاء العاديين، shared database قد تكون أكثر كفاءة. أما العملاء الكبار أو أصحاب requirements خاصة، ممكن أعطيهم dedicated database."
🎯 والسؤال الأصعب أكثر
"طيب لو عندك 10,000 Tenant؟"
ما تقولش:
10,000 Database.
وما تقولش:
TenantId وخلاص.
فكر في:
Tenant Catalog
↓
Tenant Resolution
↓
Shared / Sharded / Dedicated
↓
Tenant-aware Data Access
↓
Indexes
↓
Caching
↓
Queues
↓
Observability
↓
Noisy Neighbor Control
وده هو التفكير الصح.
🧠 الخلاصة
Multi-Tenancy مش مجرد:
Add TenantId
دي Architecture Decision.
أنت بتقرر:
Where does tenant data live?
How do I identify the tenant?
How do I enforce isolation?
How do I index the data?
How do I cache safely?
How do jobs know their tenant?
How do I prevent noisy neighbors?
How do I migrate thousands of tenants?
How do I backup/restore?
How do I scale?
How do I handle enterprise tenants?
وعشان كده مفيش:
"Best Multi-Tenancy Architecture"
فيه:
Best Architecture For Your Requirements
🏁 قاعدة عملية
لو بدأت SaaS النهارده:
Application
↓
Tenant Resolution
↓
Authentication
↓
Authorization
↓
Tenant Context
↓
Shared DB + TenantId
↓
Global Query Filter
↓
Tenant-aware Indexes
↓
Tenant-aware Cache
↓
Tenant-aware Jobs
↓
Observability
وبعد ما النظام يكبر:
Shared
↓
Partitioned
↓
Sharded
↓
Dedicated
حسب الحاجة.
مش حسب الموضة.
📚 مصادر رسمية
Microsoft — EF Core Multi-Tenancy
-
Multi-tenancy - EF Core
https://learn.microsoft.com/en-us/ef/core/miscellaneous/multitenancy citeturn0search1 -
Global Query Filters - EF Core
https://learn.microsoft.com/en-us/ef/core/querying/filters citeturn0search0
Microsoft — Azure Architecture Center
-
Architectural Approaches for Storage and Data in Multitenant Solutions
https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/approaches/storage-data citeturn0search2 -
Tenancy Models for a Multitenant Solution
https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/considerations/tenancy-models citeturn0search5 -
Multitenancy and Azure SQL Database
https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/service/sql-database citeturn0search4 -
Data Partitioning Strategies
https://learn.microsoft.com/en-us/azure/architecture/best-practices/data-partitioning-strategies citeturn0search12 -
Deployment and Configuration of Multitenant Solutions
https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/approaches/deployment-configuration citeturn0search6
PostgreSQL
- PostgreSQL Schemas
https://www.postgresql.org/docs/current/ddl-schemas.html citeturn0search7
<div align="center">
🏢 Multi-Tenancy مش إنك تخلي 1000 عميل يستخدموا نفس الـ App
التحدي الحقيقي إنك تخليهم يستخدموا نفس النظام بدون ما Tenant يشوف Tenant تاني.
Isolation + Scalability + Cost + Operations = Multi-Tenant Architecture
</div>منشورات مقترحة
مشاريع ذات صلة
منصة تعليمية تتيح تصفح الكورسات، وتشغيل الفيديو المحمي عبر روابط Cloudinary الموقعة، وتتبع تقدم الطلاب، والدفع عبر PayPal.