Đây là một câu hỏi hay, minh họa các vấn đề khi ăn quá nhiều và cách giải quyết.
Ví dụ:Lượt thích bài đăng
Hãy lấy ví dụ về việc người dùng thích bài đăng, đó là một ví dụ đơn giản. Các mối quan hệ khác sẽ phải được xử lý phù hợp.
Bạn hoàn toàn đúng khi lưu trữ lượt thích bên trong bài đăng sớm hay muộn sẽ dẫn đến vấn đề là các bài đăng rất phổ biến sẽ đạt đến giới hạn kích thước.
Vì vậy, bạn đã quay lại chính xác để tạo post_likes
thu thập. Tại sao tôi gọi điều này là chính xác? Vì nó phù hợp với các trường hợp sử dụng và các yêu cầu chức năng và phi chức năng của bạn!
- Quy mô không theo quy luật (tốt, có một giới hạn lý thuyết, nhưng nó rất lớn)
- Nó dễ duy trì (tạo một chỉ mục duy nhất trên
post_id
vàliked_user_id
) và sử dụng (cả người dùng và bài đăng đều được biết đến, vì vậy việc thêm lượt thích chỉ là một cách chèn đơn giản hoặc nhiều khả năng là một sự bổ sung) - Bạn có thể dễ dàng tìm ra người dùng thích bài đăng nào và người dùng thích bài đăng nào
Tuy nhiên, tôi sẽ mở rộng bộ sưu tập một chút để ngăn các truy vấn không cần thiết cho một số trường hợp sử dụng thường xuyên.
Bây giờ, hãy giả sử rằng không thể thay đổi tiêu đề bài đăng và tên người dùng. Trong trường hợp đó, mô hình dữ liệu sau có thể có ý nghĩa hơn
{
_id: new ObjectId(),
"post_id": someValue,
"post_title": "Cool thing",
"liked_user_id": someUserId,
"user_name": "JoeCool"
}
Bây giờ, giả sử bạn muốn hiển thị tên người dùng của tất cả người dùng đã thích một bài đăng. Với mô hình trên, đó sẽ là một truy vấn duy nhất, khá nhanh:
db.post_likes.find(
{"postId":someValue},
{_id:0,user_name:1}
)
Chỉ với các ID được lưu trữ, tác vụ khá thông thường này sẽ cần ít nhất hai truy vấn và - với điều kiện ràng buộc rằng có thể có vô số người thích cho một bài đăng - có khả năng rất lớn tiêu thụ bộ nhớ (bạn cần lưu trữ ID người dùng trong RAM).
Tuy nhiên, điều này dẫn đến một số dư thừa, nhưng ngay cả khi hàng triệu người thích một bài đăng, chúng ta chỉ đang nói về một vài MB dung lượng đĩa tương đối rẻ (và dễ mở rộng) trong khi đạt được rất nhiều hiệu suất về trải nghiệm người dùng.
Bây giờ đến đây là vấn đề:Ngay cả khi tên người dùng và tiêu đề bài đăng có thể thay đổi, bạn chỉ phải thực hiện cập nhật nhiều lần:
db.post_likes.update(
{"post_id":someId},
{ $set:{ "post_title":newTitle} },
{ multi: true}
)
Bạn đang giao dịch rằng phải mất một khoảng thời gian để thực hiện một số việc khá hiếm như thay đổi tên người dùng hoặc một bài đăng để có tốc độ cực cao cho các trường hợp sử dụng xảy ra cực kỳ thường xuyên.
Điểm mấu chốt
Hãy nhớ rằng MongoDB là một cơ sở dữ liệu hướng tài liệu. Vì vậy, ghi lại các sự kiện bạn quan tâm với các giá trị bạn cần cho các truy vấn trong tương lai và lập mô hình dữ liệu của bạn cho phù hợp.