Databases
When a document model quietly becomes a relational one
MongoDB schemas start flexible and end up needing the same normalization discipline as a relational database, just without the tooling that enforces it.
Last updated September 17, 2026
MongoDB's pitch is schema flexibility, and the early modeling instinct that flexibility encourages is embedding: put related data directly inside the parent document, since there's no join to avoid and no schema migration to run. This works well right up until it doesn't, and the point where it stops working is predictable enough to plan around instead of discovering the hard way.
Where embedding starts to hurt
The warning sign is an embedded array that grows without a natural bound — comments on a post, orders on a customer, events on a session. Each of these looks fine with ten items and becomes a real problem with ten thousand: MongoDB documents have a hard 16MB size limit, but long before hitting that ceiling, a document with a huge embedded array means every read and write to that document moves the entire array over the wire, even for an operation that only touched one element of it.
// This works fine until a customer has thousands of orders
{
_id: "customer123",
name: "...",
orders: [ /* thousands of embedded order documents */ ]
}
References bring back what embedding was avoiding
The fix is referencing instead of embedding — store orders as their own collection with a customerId field, and look them up separately.
// orders collection
{ _id: "order1", customerId: "customer123", ... }
{ _id: "order2", customerId: "customer123", ... }
This solves the unbounded-growth problem, and it reintroduces exactly the thing embedding was chosen to avoid: a second query (or an aggregation $lookup, MongoDB's version of a join) to assemble a customer with their orders. At this point the data model has become relational in every way that matters — normalized data, references instead of embedding, joins to reassemble a full view — it's just running on a document database instead of a relational one.
The part that MongoDB doesn't help with
A relational database enforces referential integrity — a foreign key constraint means an order can't reference a customer that doesn't exist, and the database rejects the write if it would. MongoDB has no equivalent by default: a customerId field is just a string, and nothing stops it from pointing at a customer that was deleted, or never existed, or was misspelled. Once a MongoDB schema has become relational in shape, it's taken on relational modeling's complexity without automatically getting relational modeling's data-integrity guarantees — those have to be enforced in application code instead, which is easy to get inconsistent across different write paths.
None of this means document databases were the wrong choice — genuinely document-shaped data (a user profile with nested preferences that's always read and written as one unit, for instance) is exactly what embedding is good at. The point where it's worth pausing is when an embedded structure has grown an unbounded list inside it — that's usually the signal that the data has outgrown the document model it started in, and the schema is quietly becoming relational whether or not anyone explicitly decided that.
Tags
Related posts