The Document Data Model & Schema Design
🧩 The Document Data Model & Schema Design
mysql_advanced_01 chapter builds around.
Embedding vs. Referencing: The Core Decision
Every relationship between two pieces of data can be represented one of two ways: embedding the related data directly inside the parent document (as Chapter 1's blog post + comments example did), or referencing it — storing just an _id pointing to a separate document in another collection, conceptually similar to a MySQL foreign key.
Embedding vs. Referencing
Embedding
Related data lives directly inside the parent document. One read gets everything — no second query needed — but the data can only grow so far before that becomes a liability.
Referencing
The parent stores just an id; the related data lives in its own collection, looked up separately. More like a relational foreign key, at the cost of a second query when you need both.
When to Embed
Embed when the related data is always read together with its parent, doesn't grow without bound, and conceptually belongs to one single "thing" — an address embedded in a user, or a handful of recent comments embedded in a post, exactly as Chapter 1 modeled it.
When to Reference
Reference when the related data is large or effectively unbounded, shared and reused across many different parent documents, or frequently queried independently of whatever "owns" it.
Referencing a Shared Category
If "Electronics" instead got embedded directly into every product document, renaming the category or changing its tax rate would mean updating potentially thousands of product documents at once — referencing means updating exactly one document.
Denormalization: A Deliberate Choice, Not Sloppiness
The MySQL course's normalization chapter treats duplicated data as something to design away. MongoDB documents often duplicate data on purpose, trading some update complexity for read performance — for example, embedding a post's author name directly on the post, not just an authorId reference, so displaying a post never needs a second lookup just to show who wrote it. The trade-off is real: if that author later changes their display name, every post that embedded the old name needs updating (or the staleness has to be accepted temporarily) — precisely the "update anomaly" relational normalization exists to prevent. MongoDB doesn't eliminate that trade-off; it just makes it a deliberate, chapter-by-chapter design choice rather than something the database forces on you either way.
One-to-Many Relationships
| Relationship Shape | Example | Recommended Pattern |
|---|---|---|
| One-to-few | A user with a few addresses | Embed as an array |
| One-to-many (bounded) | A post with a manageable number of comments | Embed, with an eye on growth |
| One-to-squillions | A device generating millions of log entries | Always reference — never embed |
Many-to-Many Relationships
Take students and courses — a student takes many courses, and a course has many students. The most direct pattern: store an array of course _ids on the student document (or vice versa). For a genuinely many-to-many relationship with its own attributes (like an enrollment date or a grade), a separate join collection often works better — the exact document-model counterpart to a MySQL join table:
A Join Collection for Enrollments
💻 Coding Challenges
Challenge 1: Embed or Reference?
For each, recommend embedding or referencing: (a) a user's shipping addresses (typically 1-3 per user), (b) a YouTube-style video's comments (potentially tens of thousands), (c) a "country" field shared by millions of user documents.
Goal: Practice applying the growth/sharing criteria this chapter introduced.
Challenge 2: Design a Many-to-Many Relationship
Design the document(s) for a many-to-many relationship between "authors" and "books" (an author can write several books; a book can have several co-authors), including a way to store each author's specific royalty percentage on a given book.
Goal: Practice the join-collection pattern for a many-to-many relationship that carries its own data.
Challenge 3: Identify a Denormalization Trade-off
A product document embeds its supplier's name directly (not just a supplierId). The supplier later rebrands and changes their name. Explain what happens to existing product documents, and how you might address it.
Goal: Practice reasoning through the real consequence of a denormalization decision made earlier.
Every MongoDB document has a hard maximum size of 16MB — not a soft guideline, an enforced limit. This is exactly why "one-to-squillions" relationships must be referenced rather than embedded: a viral post that keeps embedding new comments directly into its own document will eventually hit this ceiling, and further inserts/updates to that document will simply start failing. It's easy to overlook this while a post only has a handful of comments in testing — the failure only shows up once real growth happens, which is precisely why the growth pattern matters more than the current size when choosing between embedding and referencing.
🎯 What's Next
The next chapter covers Data Types & BSON — ObjectId, dates, arrays, and nested documents in more depth, plus schema validation with $jsonSchema for when you want to opt back into enforced structure.