Database Design and Multi-Tenancy
Tenant boundaries, MongoDB access patterns, indexes, consistency, migrations, backups, and retention
Multi-Tenant Isolation Patterns
Options include shared collections with tenant IDs, separate schemas, database-per-tenant, and hybrid isolation.
How to apply it
Scope reads, updates, deletes, aggregations, exports, search, and background jobs by verified tenant context. Add constraints and explicit cross-tenant denial tests. Choose isolation based on compliance, scale, customization, and cost.
Worked example
Query a project using both its ID and the authenticated organization ID rather than ID alone.
Common mistakes to avoid
A missed tenant filter in an export or worker can expose customer data.
Practice task
Implement this concept in the capstone. Add one positive test, one negative or failure-path test, and a short note explaining the trade-off you chose.
Every tenant-owned read, write, delete, aggregation, export, search result, and background job must enforce tenant scope.
- Options include shared collections with tenant IDs, separate schemas, database-per-tenant, and hybrid isolation.
- Scope reads, updates, deletes, aggregations, exports, search, and background jobs by verified tenant context.
What is the strongest production practice for Multi-Tenant Isolation Patterns?
MongoDB Modeling and Indexes
Model documents around access patterns; embed bounded data read with a parent and reference independently growing or shared entities.
How to apply it
Indexes speed reads but consume storage and slow writes. Design compound indexes around equality filters, sort, and range predicates. Use explain execution statistics on representative data and inspect documents examined, keys examined, and sort stages.
Worked example
A project list may benefit from an index on organizationId, createdAt descending, and _id descending; benchmark if status should also be indexed.
Common mistakes to avoid
Indexing every field or assuming one index optimizes every query.
Practice task
Implement this concept in the capstone. Add one positive test, one negative or failure-path test, and a short note explaining the trade-off you chose.
projectSchema.index({ organizationId: 1, createdAt: -1, _id: -1 });
const projects = await Project.find({
organizationId: req.auth.organizationId,
status: 'active'
}).sort({ createdAt: -1, _id: -1 }).limit(25).lean();- Model documents around access patterns; embed bounded data read with a parent and reference independently growing or shared entities.
- Indexes speed reads but consume storage and slow writes.
What is the strongest production practice for MongoDB Modeling and Indexes?
Transactions, Migrations, and Backups
Use transactions for invariants spanning records; use atomic updates and unique constraints to prevent common races.
How to apply it
Use expand-and-contract migrations: add compatible fields, deploy dual-read code, backfill, switch writes, verify, then remove legacy fields later. Encrypt backups and test restoration in isolation. Define RPO/RTO and retention across databases, object storage, logs, and exports.
Worked example
For a field rename, support old and new fields during rollout, backfill, measure remaining legacy records, then remove the old field.
Common mistakes to avoid
Assuming successful backup jobs prove recoverability or removing fields before old app versions are gone.
Practice task
Implement this concept in the capstone. Add one positive test, one negative or failure-path test, and a short note explaining the trade-off you chose.
- Use transactions for invariants spanning records; use atomic updates and unique constraints to prevent common races.
- Use expand-and-contract migrations: add compatible fields, deploy dual-read code, backfill, switch writes, verify, then remove legacy fields later.
What is the strongest production practice for Transactions, Migrations, and Backups?