The document model, and how it really differs
You have spent nine modules on the relational model. This module is the main alternative — the document model, of which MongoDB is the dominant example. The goal is not to sell it. It is to understand it well enough to know when it is the right tool and, just as important, when "just use MongoDB" was bad advice somebody gave you.
What a document is
A row in books looks like this:
id | title | author_id | copies | price
----+------------------+-----------+--------+-------
1 | The Long Monsoon | 17 | 3 | 39900
The same book as a document:
{
_id: 1,
title: "The Long Monsoon",
author: { name: "Meera Kulkarni", city: "Pune" },
categories: ["fiction", "literary"],
copies: 3,
price: 39900,
published: ISODate("2019-06-01")
}
It is JSON — technically BSON, a binary form with more types (dates, ObjectId, proper
integers, binary). The differences from a row are the whole point:
- The author is nested inside the book. No
author_id, no join — the data is right there. categoriesis an array. In the relational model this was an entire join table.- There is no fixed schema. Book 3 can have an
isbn; book 1 need not. The structure lives in each document, not in a table definition.
A collection is a group of documents — the rough equivalent of a table, but without an enforced shape.
The model in one idea
Relational: split data into flat tables, join them back at read time. Document: store data in the shape you read it, nested, and read it in one go.
That is the entire difference, and everything else follows from it. The relational model optimises for storing each fact once (module 8's normalisation). The document model optimises for reading a whole thing at once.
The library book above, fetched relationally, is a book row joined to an author row joined to category rows — three tables. As a document it is one read, already in the shape your application wants. If your access pattern is "give me this whole book and everything about it", the document model hands it to you with no assembly.
Where this genuinely helps
Not fashion — real advantages, when they apply:
The data is naturally nested and read together. A blog post with its tags and metadata; a product with its variants and specifications; an order with its line items. You almost always want the whole thing at once, and storing it as one document means fetching it is one operation.
The shape varies between records. A catalogue where a book, a DVD and a laptop have wildly different attributes. Relationally this is painful — a wide sparse table, or a table per type, or an entity-attribute-value mess. A document collection holds all three naturally, each with its own fields.
The schema changes often, early on. A startup pivoting weekly. Adding a field to a document is just writing the field; there is no migration. This is a real early-stage advantage, and one you grow out of.
Developer ergonomics. A document maps directly to an object in your code. No object-relational
mapping layer, no impedance mismatch. book.author.name in your code is book.author.name in
the database.
Where it hurts — and this is the honest half
The costs are as real as the benefits, and they are what "just use MongoDB" leaves out.
Duplicated data goes out of sync. Embed the author's name in every one of their books and renaming them means updating every book. This is exactly module 8's update anomaly — the document model reintroduces the very problem normalisation solved. Sometimes that trade is worth it; pretending it is not a trade is the mistake.
Relationships across documents are your problem. MongoDB has $lookup (a join), but it is
less capable and often slower than a relational join, and the database will not enforce that a
member_id in a loan actually points at a member. No foreign keys. An orphaned reference is
a bug the database happily stores.
No multi-document transactions by default habit. MongoDB does have them now (since 4.0), but the model pushes you toward single-document atomicity, and reaching across documents for a transaction is possible but discouraged and slower. If your data is genuinely relational — money moving between accounts — this is a poor fit.
Ad-hoc queries across the data are harder. "Average loan duration by member city crossed with
book category" is a JOIN and a GROUP BY in SQL. Across documents it is an aggregation pipeline
that is longer to write and often slower.
Unbounded arrays are a trap. Embedding "all comments" in a post works until a post has 50,000 comments and the document hits MongoDB's 16 MB limit — or just becomes slow to load because you fetch all of them to read one. The modelling lesson deals with this.
"Schemaless" is a half-truth worth dismantling
MongoDB does not enforce a schema, which is sold as freedom. The truth: the schema still exists — it has just moved from the database into your application code, undocumented.
Every place that reads a document assumes a shape. When documents drift — some have price as a
number, some as a string, some with the field missing entirely — nothing rejected the drift, and
now every reader must cope with every variation. The relational model refuses the bad write; the
document model accepts it and hands you the problem later, at read time, in production.
MongoDB's answer is schema validation — you can attach a JSON-Schema rule to a collection and have it reject non-conforming writes:
db.createCollection("books", {
validator: { $jsonSchema: {
required: ["title", "copies"],
properties: {
title: { bsonType: "string" },
copies: { bsonType: "int", minimum: 0 }
}
}}
});
Use it. A document database without validation drifts, and the drift is invisible until it breaks something. That it is optional is not a reason to skip it.
The honest positioning
The document model is not newer-and-better, nor older-and-worse. It is a different trade:
- It buys fast reads of nested things and schema flexibility with the cost of data duplication, weaker cross-document integrity, and harder ad-hoc analysis.
- The relational model buys guaranteed consistency, easy ad-hoc queries and no duplication with the cost of joins at read time and migrations to change shape.
Most web applications are more relational than they first appear — they have users, and orders, and things that relate to other things, and they need those relationships to be correct. That is why this course spends most of its time on SQL and recommends starting there. But a genuinely document-shaped problem — a content store, a product catalogue, an event log, a flexible per-customer form — is where MongoDB earns its place, and the rest of this module is how to use it well when it does.
Check your work
What a document is. A nested JSON/BSON structure stored whole — fields, nested objects, and arrays inside one record.
What a collection is. A group of documents; a table without an enforced shape.
The model in one idea. Relational splits data into flat tables and joins at read time; document stores data in the shape you read it and fetches it in one go.
What each model optimises for. Relational: storing each fact once. Document: reading a whole thing at once.
Four places the document model genuinely helps. Naturally-nested data read together, records of varying shape, frequently-changing early schemas, and direct object mapping.
Five costs. Duplicated data drifting, weak cross-document integrity (no foreign keys), transactions discouraged across documents, harder ad-hoc queries, and the unbounded-array trap.
The 16 MB limit. A single document's maximum size — why unbounded arrays are dangerous.
Why "schemaless" is a half-truth. The schema moved into application code, undocumented; drift is accepted and surfaces at read time.
MongoDB's defence against drift. Optional JSON-Schema validation on a collection — which you should use.
Why most web apps start relational. They have things that relate and must stay correct; the document model reintroduces the update anomaly normalisation solved.
Practice
- Take the library
books/authors/categoriesschema and write one book as a single document. Note what disappeared. - Write the same book as it would be denormalised into one flat relational row. Compare with the document.
- Add an
isbnto one document and not another. Note that nothing objected. - Write two documents where
priceis a number in one and a string in the other. Note that nothing objected, and describe the bug a reader now has. - List three things in an application you know that are "naturally nested and read together", and three that are "genuinely relational".
- Embed an author's name in three of their books. Rename the author and count the writes.
- Create a collection with a
$jsonSchemavalidator and try to insert a document that violates it. - Estimate how many comments would fit in a 16 MB document, and decide at what point you would stop embedding them.
- For a project you know, argue in writing whether it is more document-shaped or more relational.
Official documentation
- MongoDB — Documents — The BSON document, its types and the 16 MB limit.
- MongoDB — Databases and collections — The collection, and how it differs from a table.
- MongoDB — Schema validation — JSON-Schema rules to stop drift.
- MongoDB — Data modeling introduction — The official framing of embed-versus-reference, which the next lesson goes into.
- BSON specification — What BSON adds over JSON, if you want the detail.
Next: the decision that defines document modelling — embed or reference.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship