Data Modeling
Schema Design Philosophy
Design around how you query, not around how a spreadsheet would look.
SQL modeling starts from entities and normalises. MongoDB modeling starts from access patterns: what the hot read returns, what must update together, how fast a list grows. The document is the unit you fetch and the unit that updates atomically. Shape the document to that unit — not to a third-normal-form spreadsheet.
- Together on the read → together in the document. Rahul's profile and
skillsload as onefindOne. - Grows without bound → its own collection. Orders are not an array on the user.
- Updated together → one document. Line items sit on the order so a status change is one write.
- Flexible is not schemaless. New fields appear; the service still owns a shape. Validators later.
// Always loaded with the user — embed
db.users.findOne({ name: "Rahul" })
// { name, city, address: { line1, city, pin }, skills: [...] }
// Unbounded, queried on their own — reference
db.orders.find({ userId: ObjectId("64a1b2c3d4e5f6a7b8c90001") })Ask four questions before you draw collections: What is the most common read? What is the most common write? How large can this list get in a year? Who owns this field? If the answer to the first is 'user plus last five orders plus every review plus inventory', you do not have a schema yet — you have an unbounded join. Cut the read, then model.
Interview question
How is schema design in MongoDB different from SQL?
You design around access patterns, not around 3NF. Related data that is read and updated together is often one document. Unbounded or independently queried data stays in its own collection with a reference. Joins exist ($lookup) but a join on the hot path usually means the schema is fighting the product.