Skip to content

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 TypeUse CasePerformance Impact
Single fieldEquality + range queriesLow write overhead
CompoundMulti-field filtersMedium write overhead
TextFull-text searchHigh write overhead
UniquePrevent duplicatesLow 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" }
  ]
}