Hướng dẫn mongodb social network data model - mô hình dữ liệu mạng xã hội mongodb

Thiết kế một lược đồ là một phần quan trọng của bất kỳ ứng dụng. Giống như hầu hết các cơ sở dữ liệu, có nhiều tùy chọn để mô hình hóa dữ liệu trong MongoDB và điều quan trọng là phải kết hợp các yêu cầu chức năng và mục tiêu hiệu suất cho ứng dụng của bạn khi xác định thiết kế tốt nhất. Trong bài đăng này, chúng tôi sẽ khám phá ba cách tiếp cận để sử dụng MongoDB khi tạo các hộp thư đến xã hội hoặc các mốc thời gian nhắn tin.

Ví dụ, nếu bạn đang xây dựng một mạng xã hội, như Twitter, bạn cần thiết kế một lược đồ hiệu quả cho người dùng xem hộp thư đến của họ, cũng như người dùng gửi tin nhắn cho tất cả người theo dõi của họ. Toàn bộ quan điểm của phương tiện truyền thông xã hội, sau tất cả, là bạn có thể kết nối trong thời gian thực.

Có một số cân nhắc thiết kế cho loại ứng dụng này:

  • Ứng dụng cần hỗ trợ một khối lượng đọc và ghi lớn có khả năng.
  • Đọc và ghi không được phân phối đồng đều giữa người dùng. Một số người dùng đăng thường xuyên hơn nhiều so với những người khác và một số người dùng có nhiều, nhiều người theo dõi hơn những người khác.
  • Ứng dụng phải cung cấp trải nghiệm người dùng là tức thời.
  • Chỉnh sửa 11/6: Ứng dụng sẽ có ít hoặc không có xóa dữ liệu của người dùng (một bài đăng trên blog tiếp theo sẽ bao gồm thông tin về xóa người dùng và dữ liệu lịch sử)

Bởi vì chúng tôi đang thiết kế một ứng dụng cần hỗ trợ một khối lượng lớn các lần đọc và viết, chúng tôi sẽ sử dụng một bộ sưu tập Sharded cho các tin nhắn. Tất cả ba thiết kế bao gồm khái niệm về người hâm mộ, một trong đó đề cập đến việc phân phối công việc trên các mảnh vỡ song song:

  1. Fan Out On Read
  2. Quạt ra trên viết
  3. Quạt ra khi viết với xô

Mỗi cách tiếp cận trình bày sự đánh đổi và bạn nên sử dụng thiết kế tốt nhất cho các yêu cầu của ứng dụng của bạn.

Thiết kế đầu tiên bạn có thể xem xét được gọi là người hâm mộ khi đọc. Khi người dùng gửi tin nhắn, nó chỉ được lưu vào bộ sưu tập hộp thư đến. Khi bất kỳ người dùng nào xem hộp thư đến của riêng họ, các truy vấn ứng dụng cho tất cả các tin nhắn bao gồm người dùng là người nhận. Các tin nhắn được trả về theo thứ tự ngày giảm dần để người dùng có thể xem các tin nhắn gần đây nhất.

//Shard on "from"
db.shardCollection( "mongodbdays.inbox", {from: 1})

//Make sure we have an inbox to handle inbox reads
db.inbox.ensureIndex( {to: 1, sent: 1})

msg = {
  from: "Joe"
  to: ["Bob", "Jane"],
  sent: new Date(),
  message: "Hi!",
}

//Send a message
db.inbox.save (msg)

//Read Bob's inbox
db.inbox.find ({ to: "Bob"}).sort({sent:-1})

Để thực hiện thiết kế này, hãy tạo một bộ sưu tập Sharded có tên inbox, chỉ định trường from làm khóa Shard, đại diện cho địa chỉ gửi tin nhắn. Sau đó, bạn có thể thêm một chỉ mục ghép trên trường vào và trường đã gửi. Khi tài liệu được lưu vào hộp thư đến, tin nhắn sẽ được gửi một cách hiệu quả cho tất cả những người nhận. Với phương pháp này, việc gửi tin nhắn là rất hiệu quả.

Xem một hộp thư đến, mặt khác, kém hiệu quả hơn. Khi người dùng xem hộp thư đến của họ, ứng dụng sẽ phát hành lệnh tìm dựa trên trường to, được sắp xếp bằng cách gửi. Bởi vì bộ sưu tập hộp thư đến sử dụng from làm khóa Shard, các tin nhắn được nhóm người gửi nhóm qua các mảnh vỡ. Trong các truy vấn MongoDB không dựa trên khóa Shard sẽ được chuyển đến tất cả các mảnh vỡ. Do đó, mỗi chế độ xem hộp thư đến sẽ được chuyển đến tất cả các mảnh vỡ trong hệ thống. Khi hệ thống chia tỷ lệ và nhiều người dùng đi xem hộp thư đến của họ, tất cả các truy vấn sẽ được chuyển đến tất cả các mảnh vỡ. Thiết kế này không mở rộng quy mô cũng như mỗi truy vấn được chuyển đến một mảnh vỡ.

Hướng dẫn mongodb social network data model - mô hình dữ liệu mạng xã hội mongodb

Với phương thức của người hâm mộ trên phương thức đọc, việc gửi tin nhắn rất hiệu quả, nhưng việc xem hộp thư đến kém hiệu quả.

Quạt ra trên Read là rất hiệu quả để gửi tin nhắn, nhưng kém hiệu quả để đọc tin nhắn. Nếu phần lớn ứng dụng của bạn bao gồm người dùng gửi tin nhắn, nhưng rất ít người đi đọc những gì mọi người gửi cho họ-hãy để Lôi gọi nó là một ứng dụng chống đối xã hội-thì thiết kế này có thể hoạt động tốt. Tuy nhiên, đối với hầu hết các ứng dụng xã hội, có nhiều yêu cầu của người dùng để xem hộp thư đến của họ hơn là gửi tin nhắn.

Quạt ra trên Write có một cách tiếp cận khác được tối ưu hóa hơn để xem các hộp thư đến. Lần này, thay vì thu thập bộ sưu tập hộp thư đến của chúng tôi trên người gửi, chúng tôi chia nhỏ người nhận tin nhắn. Theo cách này, khi chúng tôi đi xem một hộp thư đến, các truy vấn có thể được chuyển đến một mảnh vỡ duy nhất, sẽ mở rộng quy mô rất tốt. Tài liệu tin nhắn của chúng tôi là như nhau, nhưng bây giờ lưu một bản sao của tin nhắn cho mỗi người nhận. takes a different approach that is more optimized for viewing inboxes. This time, instead of sharding our inbox collection on the sender, we shard on the message recipient. In this way, when we go to view an inbox the queries can be routed to a single shard, which will scale very well. Our message document is the same, but now save a copy of the message for every recipient.

//Shard on "recipient" and "sent"
db.shardCollection("mongodbdays.inbox", {"recipient": 1, "sent":1})

msg = {
  from: "Joe",
  to: ["Bob", "Jane"]
  sent: new Date()
  message: "Hi!", 
}

//Send a message
for (recipient in msg.to){
  msg.recipient = msg.to[recipient]
  db.inbox.insert(msg);
}

//Read Bob's inbox
db.inbox.find ({recipient: "Bob"}).sort({ sent:-1})

Hướng dẫn mongodb social network data model - mô hình dữ liệu mạng xã hội mongodb

Với phương thức của người hâm mộ trên phương thức ghi, xem hộp thư đến là hiệu quả, nhưng việc gửi tin nhắn tiêu thụ nhiều tài nguyên hơn.

Trong thực tế, chúng tôi có thể thực hiện việc lưu các tin nhắn không đồng bộ. Hãy tưởng tượng hai người nổi tiếng nhanh chóng trao đổi tin nhắn tại một sự kiện cao cấp - hệ thống có thể nhanh chóng bị bão hòa với hàng triệu bài viết. Bằng cách lưu một bản sao đầu tiên của tin nhắn của họ, sau đó sử dụng một nhóm nhân viên nền để viết bản sao cho tất cả những người theo dõi, chúng tôi có thể đảm bảo hai người nổi tiếng có thể trao đổi tin nhắn nhanh chóng và những người theo dõi sẽ sớm có bản sao của họ. Hơn nữa, chúng tôi có thể duy trì một ngày được xem cuối cùng trên tài liệu người dùng để đảm bảo họ đã truy cập hệ thống gần đây - tài khoản zombie có thể không nhận được một bản sao của tin nhắn và đối với người dùng chưa truy cập tài khoản của họ gần đây, chúng tôi luôn có thể Khu dùng đến thiết kế đầu tiên của chúng tôi - người hâm mộ trên Read - để tái lập hộp thư đến của họ. Các yêu cầu tiếp theo sau đó sẽ nhanh chóng trở lại.

Tại thời điểm này, chúng tôi đã cải thiện thiết kế để xem các hộp thư đến bằng cách định tuyến từng chế độ xem hộp thư đến thành một mảnh vỡ. Tuy nhiên, mỗi tin nhắn trong hộp thư đến người dùng sẽ tạo ra một thao tác đọc ngẫu nhiên. Nếu mỗi chế độ xem hộp thư đến tạo ra 50 lần đọc ngẫu nhiên, thì nó chỉ cần một số lượng người dùng đồng thời tương đối khiêm tốn để có khả năng bão hòa các đĩa. May mắn thay, chúng tôi có thể tận dụng mô hình dữ liệu tài liệu để tối ưu hóa hơn nữa thiết kế này để hiệu quả hơn.

Fan out On Writing With Buckets tinh chỉnh quạt ra trên thiết kế viết bằng cách sử dụng các tin nhắn của nhóm các tin nhắn với nhau thành tài liệu của 50 tin nhắn được đặt hàng theo thời gian. Khi người dùng xem hộp thư đến của họ, yêu cầu có thể được thực hiện bằng cách đọc chỉ một vài tài liệu gồm 50 tin nhắn thay vì thực hiện nhiều lần đọc ngẫu nhiên. Bởi vì thời gian đọc bị chi phối bởi thời gian tìm kiếm, việc giảm số lượng tìm kiếm có thể cung cấp một cải tiến hiệu suất lớn cho ứng dụng. Một lợi thế khác cho phương pháp này là có ít mục chỉ mục hơn.

Để thực hiện thiết kế này, chúng tôi tạo hai bộ sưu tập, bộ sưu tập hộp thư đến và bộ sưu tập người dùng. Bộ sưu tập Hộp thư đến sử dụng hai trường cho khóa Shard, ownersequence, giữ ID người dùng và số trình tự của chủ sở hữu (nghĩa là ID của tài liệu Xô Bucket 50-Message trong hộp thư đến của họ). Bộ sưu tập người dùng chứa các tài liệu người dùng đơn giản để theo dõi tổng số tin nhắn trong hộp thư đến của họ. Vì chúng tôi có thể sẽ cần hiển thị tổng số tin nhắn cho người dùng ở nhiều nơi trong ứng dụng của chúng tôi, đây là một nơi tốt đẹp để duy trì số lượng thay vì tính toán cho mỗi yêu cầu. Tài liệu tin nhắn của chúng tôi giống như trong các ví dụ trước.

//Shard on "owner/sequence"
db.shardCollection("mongodbdays.inbox",
  {owner: 1, sequence: 1})
db.shardCollection("mongodbdays.users", {user_name: 1})

msg={
  from: "Joe",
  to: ["Bob", "Jane"],
  sent: new Date ()
  message: "Hi!", 
}
//Send a message
for(recipient in msg.to) {
  count = db.users.findAndModify({
    query: {user_name: msg.to[recipient]}, 
  update:{"$inc":{"msg_count":1}},
  upsert: true,
  new: true}).msg_count;

  sequence = Math.floor(count/50);

  db.inbox.update({
    owner: msg.to[recipient], sequence: sequence},
    {$push:{"messages":msg}},
    {upsert: true});
}

//Read Bob's inbox
db.inbox.find ({owner: "Bob"})
  .sort({sequence:-1}).limit(2)

Để gửi tin nhắn, chúng tôi lặp lại qua danh sách người nhận như chúng tôi đã làm trong ví dụ về người hâm mộ, nhưng chúng tôi cũng thực hiện một bước nữa để tăng số lượng tin nhắn trong hộp thư đến của người nhận, được duy trì trên tài liệu người dùng. Khi chúng ta biết số lượng tin nhắn, chúng ta biết nhóm xô của người dùng để thêm tin nhắn mới nhất. Khi các thông báo này đạt đến ngưỡng 50 mục, số trình tự tăng và chúng tôi bắt đầu thêm tin nhắn vào tài liệu tiếp theo của nhóm. Các tin nhắn gần đây nhất sẽ luôn nằm trong tài liệu của nhóm xô với số trình tự cao nhất. Xem 50 tin nhắn gần đây nhất cho hộp thư đến người dùng là nhiều nhất là hai lần đọc; Xem 100 tin nhắn gần đây nhất là nhiều nhất là ba lần đọc.Fan out on Write example, but we also take another step to increment the count of total messages in the inbox of the recipient, which is maintained on the user document. Once we know the count of messages, we know the “bucket” in which to add the latest message. As these messages reach the 50 item threshold, the sequence number increments and we begin to add messages to the next “bucket” document. The most recent messages will always be in the “bucket” document with the highest sequence number. Viewing the most recent 50 messages for a user’s inbox is at most two reads; viewing the most recent 100 messages is at most three reads.

Thông thường, toàn bộ hộp thư đến của người dùng sẽ tồn tại trên một mảnh vỡ. Tuy nhiên, có thể một vài hộp thư đến người dùng có thể được trải đều trên hai mảnh vỡ. Bởi vì ứng dụng của chúng tôi có thể sẽ trang thông qua hộp thư đến người dùng, nhưng vẫn có khả năng mọi truy vấn cho vài người dùng này sẽ được chuyển đến một mảnh vỡ.

Fan Out On Write với xô nói chung là cách tiếp cận có thể mở rộng nhất trong ba thiết kế này cho các ứng dụng hộp thư đến xã hội. Mỗi thiết kế trình bày sự đánh đổi khác nhau. Trong trường hợp này, việc xem hộp thư đến người dùng rất hiệu quả, nhưng ghi có phần phức tạp hơn và nhiều không gian đĩa được tiêu thụ. Đối với nhiều ứng dụng, đây là sự đánh đổi đúng đắn để thực hiện.

Hướng dẫn mongodb social network data model - mô hình dữ liệu mạng xã hội mongodb

Thiết kế lược đồ là một trong những tối ưu hóa quan trọng nhất mà bạn có thể thực hiện cho ứng dụng của mình. Chúng tôi có một số tài nguyên bổ sung có sẵn trong thiết kế lược đồ nếu bạn quan tâm đến việc tìm hiểu thêm:

Fan Out On Read Quạt ra trên viết Quạt ra khi viết với xô
Gửi hiệu suất tin nhắn Viết đơn tốt nhất
Single write
Shard tốt cho mỗi người nhận nhiều văn bản
Shard per recipient
Multiple writes
Shard tồi tệ nhất cho mỗi người nhận thêm (phát triển)
Shard per recipient
Appends (grows)
Đọc hiệu suất hộp thư đến Phát sóng tồi tệ nhất tất cả các mảnh vỡ các mảnh ngẫu nhiên
Broadcast all shards
Random reads
Single Single Single Random Reads
Single shard
Random reads
Shardsingle đọc tốt nhất
Single shard
Single read
Kích thước dữ liệu BestMessage được lưu trữ một lần
Message stored once
Sao chép tồi tệ nhất cho mỗi người nhận
Copy per recipient
Sao chép tồi tệ nhất cho mỗi người nhận
Copy per recipient


Thiết kế lược đồ là một trong những tối ưu hóa quan trọng nhất mà bạn có thể thực hiện cho ứng dụng của mình. Chúng tôi có một số tài nguyên bổ sung có sẵn trong thiết kế lược đồ nếu bạn quan tâm đến việc tìm hiểu thêm:

  • Kiểm tra bản ghi của hội thảo trực tuyến thiết kế lược đồ gần đây của chúng tôi về chủ đề này.
  • Thiết kế lược đồ nói chung trong Hướng dẫn MongoDB
  • Bạn cũng có thể xem tài nguyên thiết kế lược đồ của chúng tôi trên trang Docs MongoDB
  • Nếu bạn có bất kỳ câu hỏi thiết kế lược đồ nào, vui lòng xem các câu hỏi được lưu trữ trên diễn đàn người dùng của chúng tôi hoặc tự đặt câu hỏi cho diễn đàn người dùng MongoDB.

MongoDB sử dụng mô hình dữ liệu nào?

MongoDB cung cấp hai loại mô hình dữ liệu: - Mô hình dữ liệu nhúng và mô hình dữ liệu được chuẩn hóa.Embedded data model and Normalized data model.

NoQuery có tốt cho các mạng xã hội không?

Một trong những lợi ích chính của cơ sở dữ liệu NoQuery là họ cho phép người dùng điều chỉnh sự đánh đổi giữa khả năng mở rộng và chất lượng dữ liệu một cách linh hoạt.Việc phân tích cơ sở dữ liệu được sử dụng bởi SNS hàng đầu cho thấy các SNS này đã sử dụng cả cơ sở dữ liệu cả, quan hệ và NoQuery, để giải quyết các yêu cầu của người dùng khác nhau.they allow users to tune the tradeoff between scalability and data quality dynamically. The analysis of databases used by top SNSs showed that these SNSs used the both, relational and NoSQL databases, for resolving different user requirements.

MongoDB có phải là cơ sở dữ liệu mạng không?

MongoDB, ví dụ, là cơ sở dữ liệu phân tán, dựa trên tài liệu, dựa trên tài liệu được xây dựng cho các nhà phát triển ứng dụng hiện đại.

MongoDB có tốt cho ứng dụng trò chuyện không?

MongoDB được sử dụng cho nhiều ứng dụng trò chuyện.Các lợi ích chính liên quan đến mô hình tài liệu cho phép bạn mở rộng ứng dụng một cách liền mạch khi bạn xây dựng chức năng.. The primary benefits associated with the document model enable you to seamlessly extend your application as you build functionality.