MongoDB normalization, foreign key and joining
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
MongoDB is a powerful NoSQL database that differs fundamentally from traditional relational database systems. It stores data in a flexible, JSON-like format known as BSON, which stands for Binary JSON. In this article, we delve into the intricacies of MongoDB normalization, how it handles foreign keys, and the approach to joining data.
Understanding Normalization in MongoDB
Normalization is the process of structuring a database to reduce redundancy and improve data integrity. In relational databases, data is often divided into multiple tables, minimizing duplication by making use of primary and foreign keys. MongoDB, however, often embraces a denormalized model due to its document-based storage system.
Pros and Cons of Normalization in MongoDB
| Pros of Normalization | Cons of Normalization |
| Reduces data redundancy | Can complicate queries and data retrieval |
| Minimizes update anomalies | May reduce performance due to multiple collections |
| Ensures data integrity | Increased overhead in designing a normalized schema |
When to Normalize in MongoDB
While MongoDB typically operates with a denormalized model, there are scenarios where normalization is beneficial:
- Complex Relationships: When handling complex relationships that require cross-referencing multiple collections.
- Data Consistency: To ensure data consistency across collections.
- Space Constraints: When storage space is a premium and minimizing redundancy can save significant storage.
Handling Foreign Keys in MongoDB
In a relational database, a foreign key is a constraint used to link two tables together. MongoDB does not support foreign keys as a constraint, but you can emulate similar behavior.
Using References in MongoDB
MongoDB can store references by including the ObjectId of a document in another document. This approach mimics foreign keys:
In this example, the Orders collection references the Users collection by storing the _id from the Users collection in the userId field.
Joining Data in MongoDB
Joining data in MongoDB is not the same as in SQL, where the JOIN clause is used. MongoDB, being non-relational, handles joins by embedding documents or using the $lookup aggregation.
Embedding Documents
In some instances, MongoDB achieves the functionality of joining by embedding related documents directly within a document. This approach is beneficial when:
- The related dataset is small and highly related.
- There's no need to query the embedded document independently.
Using $lookup Aggregation
MongoDB 3.2 introduced the $lookup stage for performing joins across collections within an aggregation pipeline:
This query will join the Orders collection with the Users collection, producing a new field userDetails containing all matching documents from the Users collection.
Practical Example of Normalization in MongoDB
Consider a bookstore application where you have two collections, authors and books:
- Authors Collection:
- Books Collection:
To retrieve books along with their author data using $lookup, your aggregation pipeline might look like this:
This will effectively "join" the two collections, embedding author details with each book.
Final Thoughts
MongoDB's flexibility allows for various data modeling strategies, either through embedding (denormalization) or referencing (normalization). While it doesn't support traditional foreign keys or SQL-like joins natively, it offers powerful tools like the $lookup aggregation stage to manage related datasets. Understanding these mechanisms is crucial for designing efficient, scalable applications using MongoDB.

