Home Database Mysql Tutorial Schema Design for Social Inboxes in MongoDB

Schema Design for Social Inboxes in MongoDB

Jun 07, 2016 pm 04:32 PM
Design for social

Designing a schema is a critical part of any application. Like most databases, there are many options for modeling data in MongoDB, and it is important to incorporate the functional requirements and performance goals for your application w

Designing a schema is a critical part of any application. Like most databases, there are many options for modeling data in MongoDB, and it is important to incorporate the functional requirements and performance goals for your application when determining the best design. In this post, we’ll explore three approaches for using MongoDB when creating social inboxes or message timelines.

If you’re building a social network, like Twitter for example, you need to design a schema that is efficient for users viewing their inbox, as well as users sending messages to all their followers. The whole point of social media, after all, is that you can connect in real time.

There are several design considerations for this kind of application:

  • The application needs to support a potentially large volume of reads and writes.
  • Reads and writes are not uniformly distributed across users. Some users post much more frequently than others, and some users have many, many more followers than others.
  • The application must provide a user experience that is instantaneous.
  • Edit 11/6: The application will have little to no user deletions of data (a follow up blog post will include information about user deletions and historical data)

Because we are designing an application that needs to support a large volume of reads and writes we will be using a sharded collection for the messages. All three designs include the concept of “fan out,” which refers to distributing the work across the shards in parallel:

  1. Fan out on Read
  2. Fan out on Write
  3. Fan out on Write with Buckets

Each approach presents trade-offs, and you should use the design that is best for your application’s requirements.

The first design you might consider is called Fan Out on Read. When a user sends a message, it is simply saved to the inbox collection. When any user views their own inbox, the application queries for all messages that include the user as a recipient. The messages are returned in descending date order so that users can see the most recent messages.

To implement this design, create a sharded collection called inbox, specifying the from field as the shard key, which represents the address sending the message. You can then add a compound index on the to field and the sent field. Once the document is saved into the inbox, the message is effectively sent to all the recipients. With this approach sending messages is very efficient.

Viewing an inbox, on the other hand, is less efficient. When a user views their inbox the application issues a find command based on the to field, sorted by sent. Because the inbox collection uses from as its shard key, messages are grouped by sender across the shards. In MongoDB queries that are not based on the shard key will be routed to all shards. Therefore, each inbox view will be routed to all shards in the system. As the system scales and many users go to view their inbox, all queries will be routed to all shards. This design does not scale as well as each query being routed to a single shard.

With the “Fan Out on Read” method, sending a message is very efficient, but viewing the inbox is less efficient.

Fan out on Read is very efficient for sending messages, but less efficient for reading messages. If the majority of your application consists of users sending messages, but very few go to read what anyone sends them — let’s call it an anti-social app — then this design might work well. However, for most social apps there are more requests by users to view their inbox than there are to send messages.

The Fan out on Write 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.

With the “Fan Out on Write” method, viewing the inbox is efficient, but sending messages consumes more resources.

In practice we might implement the saving of messages asynchronously. Imagine two celebrities quickly exchange messages at a high-profile event - the system could quickly be saturated with millions of writes. By saving a first copy of their message, then using a pool of background workers to write copies to all followers, we can ensure the two celebrities can exchange messages quickly, and that followers will soon have their own copies. Furthermore, we could maintain a last-viewed date on the user document to ensure they have accessed the system recently - zombie accounts probably shouldn’t get a copy of the message, and for users that haven’t accessed their account recently we could always resort to our first design - Fan out on Read - to repopulate their inbox. Subsequent requests would then be fast again.

At this point we have improved the design for viewing inboxes by routing each inbox view to a single shard. However, each message in the user’s inbox will produce a random read operation. If each inbox view produces 50 random reads, then it only takes a relatively modest number of concurrent users to potentially saturate the disks. Fortunately we can take advantage of the document data model to further optimize this design to be even more efficient.

Fan out on Write with Buckets refines the Fan Out on Write design by “bucketing” messages together into documents of 50 messages ordered by time. When a user views their inbox the request can be fulfilled by reading just a few documents of 50 messages each instead of performing many random reads. Because read time is dominated by seek time, reducing the number of seeks can provide a major performance improvement to the application. Another advantage to this approach is that there are fewer index entries.

To implement this design we create two collections, an inbox collection and a user collection. The inbox collection uses two fields for the shard key, owner and sequence, which holds the owner’s user id and sequence number (i.e. the id of 50-message “bucket” documents in their inbox). The user collection contains simple user documents for tracking the total number of messages in their inbox. Since we will probably need to show the total number of messages for a user in a variety of places in our application, this is a nice place to maintain the count instead of calculating for each request. Our message document is the same as in the prior examples.

To send a message we iterate through the list of recipients as we did in the 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.

Normally a user’s entire inbox will exist on a single shard. However, it is possible that a few user inboxes could be spread across two shards. Because our application will probably page through a user’s inbox, it is still likely that every query for these few users will be routed to a single shard.

Fan out on Write with Buckets is generally the most scalable approach of the these three designs for social inbox applications. Every design presents different trade-offs. In this case viewing a user’s inbox is very efficient, but writes are somewhat more complex, and more disk space is consumed. For many applications these are the right trade-offs to make.

Schema design is one of the most important optimizations you can make for your application. We have a number of additional resources available on schema design if you are interested in learning more:

Fan out on Read
Fan out on Write
Fan out on Write with Buckets
Send Message Performance
Best
Single write
Good
Shard per recipient
Multiple writes
Worst
Shard per recipient
Appends (grows)
Read Inbox Performance
Worst
Broadcast all shards
Random reads
Good
Single shard
Random reads
Best
Single shard
Single read
Data Size
Best
Message stored once
Worst
Copy per recipient
Worst
Copy per recipient


Schema design is one of the most important optimizations you can make for your application. We have a number of additional resources available on schema design if you are interested in learning more:

  • Check out the recording of our recent Schema Design webinar on this topic.
  • Schema Design in general in the MongoDB Manual
  • You can also view our schema design resources on the MongoDB docs page
  • If you have any schema design questions, please view the archived questions on our user forum or ask a question yourselfon the MongoDB User Forum.
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Have Crossplay?
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

17 ways to solve the kernel_security_check_failure blue screen 17 ways to solve the kernel_security_check_failure blue screen Feb 12, 2024 pm 08:51 PM

Kernelsecuritycheckfailure (kernel check failure) is a relatively common type of stop code. However, no matter what the reason is, the blue screen error causes many users to be very distressed. Let this site carefully introduce 17 types to users. Solution. 17 solutions to kernel_security_check_failure blue screen Method 1: Remove all external devices When any external device you are using is incompatible with your version of Windows, the Kernelsecuritycheckfailure blue screen error may occur. To do this, you need to unplug all external devices before trying to restart your computer.

Nothing shows brand new design of the CMF Watch Pro 2, reveals curious details about the CMF Phone 1 Nothing shows brand new design of the CMF Watch Pro 2, reveals curious details about the CMF Phone 1 Jun 27, 2024 am 10:42 AM

Nothing already announced last week that three new products will be unveiled on July 8, 2024: the CMF Watch Pro 2, the CMF Phone 1, and the CMF Buds Pro 2. Now the manufacturer has released teaser images revealing new design details for these product

How to uninstall Skype for Business on Win10? How to completely uninstall Skype on your computer How to uninstall Skype for Business on Win10? How to completely uninstall Skype on your computer Feb 13, 2024 pm 12:30 PM

Can Win10 skype be uninstalled? This is a question that many users want to know, because many users find that this application is included in the default program on their computers, and they are worried that deleting it will affect the operation of the system. Let this website help users Let’s take a closer look at how to uninstall Skype for Business in Win10. How to uninstall Skype for Business in Win10 1. Click the Windows icon on the computer desktop, and then click the settings icon to enter. 2. Click "Apply". 3. Enter "Skype" in the search box and click to select the found result. 4. Click "Uninstall". 5

Cybertruck owner reviews the new Tactical Grey interior design and delivery experience Cybertruck owner reviews the new Tactical Grey interior design and delivery experience Jun 30, 2024 pm 09:44 PM

Besides the snazzy but easy to stain white Cybertruck interior available at launch, Tesla now also has the electric pickup available in a more color. The new Tactical Grey Cybertruck interior color has gotten its first preview thanks to one lucky new

How to use for to find the factorial of n in JavaScript How to use for to find the factorial of n in JavaScript Dec 08, 2021 pm 06:04 PM

How to use for to find n factorial: 1. Use the "for (var i=1;i<=n;i++){}" statement to control the loop traversal range to "1~n"; 2. In the loop body, use "cj *=i" Multiply the numbers from 1 to n, and assign the product to the variable cj; 3. After the loop ends, the value of the variable cj is the factorial of n, and then output it.

HMD Slate Tab 5G leakes as mid-range tablet with Snapdragon 7s Gen 2, 10.6-inch display and Lumia design HMD Slate Tab 5G leakes as mid-range tablet with Snapdragon 7s Gen 2, 10.6-inch display and Lumia design Jun 18, 2024 pm 05:46 PM

With the Skyline, HMD Global is set to unveil a mid-range smartphone in the style of the Nokia Lumia 920 on July 10. According to the latest information from the leaker @smashx_60, the Lumia design will soon also be used for a tablet, which will be c

What is the difference between foreach and for loop What is the difference between foreach and for loop Jan 05, 2023 pm 04:26 PM

Difference: 1. for loops through each data element through the index, while forEach loops through the data elements of the array through the JS underlying program; 2. for can terminate the execution of the loop through the break keyword, but forEach cannot; 3. for can control the execution of the loop by controlling the value of the loop variable, but forEach cannot; 4. for can call loop variables outside the loop, but forEach cannot call loop variables outside the loop; 5. The execution efficiency of for is higher than forEach.

What are the common flow control structures in Python? What are the common flow control structures in Python? Jan 20, 2024 am 08:17 AM

What are the common flow control structures in Python? In Python, the flow control structure is an important tool used to determine the execution order of the program. They allow us to execute different blocks of code based on different conditions, or to execute a block of code repeatedly. The following will introduce common process control structures in Python and provide corresponding code examples. Conditional statements (if-else): Conditional statements allow us to execute different blocks of code based on different conditions. Its basic syntax is: if condition 1: #when condition

See all articles