Hello and welcome back! As a quick reminder, in our previous lesson, we learned about the essential data types that MongoDB supports. In this lesson, we'll delve into a crucial part of database design — relationships, specifically "One-to-One" relations. We will explore how to model data in MongoDB to represent one-to-one relationships using embedded documents and references, along with the advantages and disadvantages of each approach.
Data modeling is the process of determining the best way to store data. In MongoDB, we have a lot of flexibility, but it's essential to understand this flexibility to avoid performance pitfalls. To determine the optimal way to store data, consider the following:
- Which data does your service use? This question helps you understand which collections you might need and which fields the documents in the collections will have. For example, if you're building a database for a Book Store, you'll probably need a
books
collection with fields liketitle
,description
,price
, andavailableQuantity
. - Another important question is about the data you need in different components or pages of your app. As an example, let's consider the Book Store application again, where you have a Users List Page, User Details Page, Books List Page, and Book Details Page. You'll probably need at least two collections:
books
andusers
. You can useusers.find()
to display the data on the Users List Page andusers.findOne({_id: '<user_id>'})
to display the data on the User Details Page. Similarly, you can usebooks.find()
to display the data on the Books List Page andbooks.findOne({_id: '<book_id>'})
to display the data on the Book Details Page.
In databases, relationships denote how data entities are connected. Relations can be categorized into three primary types:
- One-to-One: A single entity A is related to a single entity B. For instance, every Book Store Customer has a unique Purchase History, and this particular Purchase History belongs exclusively to that Customer.
- One-to-Many: A single entity A is related to multiple entities in B. A good example would be reviews about the books. Every book can have reviews left by multiple users. However, a single review would not be associated with multiple books.
- Many-to-Many: Multiple entities in A are related to multiple entities in B. An example here would be the relations between books and authors. One author can write many books, and one book can have multiple co-authors.
In this lesson, we will focus on one-to-one relationships. We will dive into other types of relationships like one-to-many and many-to-many in subsequent lessons.
One-to-One relationships refer to a situation where a single entity instance is related to another single entity instance. Here are a few examples:
- A person and their passport: Every single person can have only one passport and one passport can belong to this specific person.
- A student and their school ID card: Each student possesses a unique school ID card, and this ID card is specific to that student alone.
- A user and their profile: Each user has a unique profile, and each profile is associated with only one user.
- A country and its president: Each country is led by one president, and a president can only serve one country at a time.
There are two ways to implement one-to-one relations in MongoDB:
- Using Embedded Documents
- Using References
Let's dive into more practical examples!
Here’s an example of representing a one-to-one relationship using embedded documents. We’ll use the library database library_db
to store books and their selling statistics:
JavaScript1use library_db 2 3db.books.insertOne({ 4 title: "1984", 5 selling_stats: { 6 copies_sold: 5000000, 7 revenue: 25000000 8 }, 9 published_year: 1949 10});
In this code, we use db.books.insertOne()
to add a book document to the books
collection. The selling stats are embedded within the book document. The advantage of this approach is its simplicity; you can fetch a single document from the database and have all the necessary information at a glance. This works well when you don't store too much information. Problems can arise when your data exceeds MongoDB's 16MB document size limit.
In contrast, here's an example of representing a one-to-one relationship using references:
JavaScript1use library_db 2 3const sellingStatsId = ObjectId("507f191e810c19729de860ea"); 4 5db.selling_stats.insertOne({ 6 _id: sellingStatsId, 7 copies_sold: 3000000, 8 revenue: 15000000 9}); 10 11db.books.insertOne({ 12 title: "To Kill a Mockingbird", 13 selling_stats: sellingStatsId, 14 published_year: 1960 15});
In this example, we first store the ID of the selling stats document in a constant sellingStatsId
. Then, we use this constant to both insert the selling stats document into the selling_stats
collection and to reference this document in the books
collection. The benefit of this approach is that you won't face the 16MB document size limit. Additionally, this approach is more adaptable for future expansions. However, it requires multiple queries or a complex aggregate lookup query to retrieve the data, which can impact performance.
When deciding between using embedded documents and references for one-to-one relationships in MongoDB, you can consider the following rules:
- Use Embedded Documents: When the related data is tightly coupled, will not grow large, and when you need quick read operations.
- Use References: When the related data might grow large, is likely to change independently, or when you need more flexibility in data structure.
Today, you learned the two main ways to implement one-to-one relations in MongoDB: using embedded documents and using references. We discussed examples of one-to-one relationships such as a person and their passport, a student and their school ID card, a user and their profile, and a country and its president. Each method, embedded documents and references, has its own advantages and disadvantages, and the choice between them depends on the specific requirements of your application. Keep practicing both methods to become proficient in MongoDB data modeling and relationship management.