Data Modeling Best Practices
Schema Design Principles
Good schema design in NexusDB balances query performance with data integrity. Follow these principles:
- Model for your queries — design schemas around how you read data, not just how you write it
- Denormalize when needed — duplicating data is acceptable when it eliminates expensive joins
- Use indexes strategically — index fields you filter and sort by, but avoid over-indexing
Embedding vs References
Embed When:
- Data is always accessed together
- The embedded document is small (under 10KB)
- Updates to embedded data are infrequent
{
"name": "Order #1234",
"customer": {
"name": "Jane Doe",
"email": "jane@example.com"
},
"items": [
{ "product": "Widget A", "qty": 2, "price": 29.99 },
{ "product": "Widget B", "qty": 1, "price": 49.99 }
]
}Reference When:
- Data is shared across many documents
- The related document is large or frequently updated
- You need to query the related data independently
{
"name": "Order #1234",
"customer_id": "usr_abc123",
"item_ids": ["prod_001", "prod_002"]
}Index Strategies
| Index Type | Use Case | Performance Impact |
|---|---|---|
| Single field | Equality + range queries | Low write overhead |
| Compound | Multi-field filters | Medium write overhead |
| Text | Full-text search | High write overhead |
| Unique | Prevent duplicates | Low write overhead |
// Create a compound index
await db.collection("orders").createIndex({
fields: ["status", "created_at"],
direction: ["asc", "desc"]
});Common Patterns
Polymorphic Collections
Use a type field to store different document shapes in one collection:
{
"type": "blog_post",
"title": "My Article",
"content": "..."
}
{
"type": "event",
"title": "Conference 2024",
"date": "2024-06-15",
"location": "Berlin"
}Versioning
{
"_version": 3,
"title": "Updated Document",
"_history": [
{ "_version": 1, "title": "Original", "modified_at": "2024-01-01" },
{ "_version": 2, "title": "First Edit", "modified_at": "2024-02-15" }
]
}