Learn, develop, and innovate from anywhere. Join us for our MongoDB .Live series.
HomeLearnArticle

The Top 4 Reasons Why You Should Use MongoDB

Published: Mar 25, 2020

  • MongoDB
  • SQL

By Lauren Schaefer

Share

Welcome (or welcome back!) to the SQL to MongoDB series. In the first post in this series, I mapped terms and concepts from SQL to MongoDB.

I also introduced you to Ron. Let's take a moment and return to Ron. Ron is pretty set in his ways. For example, he loves his typewriter. It doesn't matter that computers are a bajillion times more powerful than typewriters. Until someone convinces him otherwise, he's sticking with his typewriter.

Ron sits at his typewriter and says, "I'm gonna type every word I know."

Maybe you don't have a love for typewriters. But perhaps you have a love for SQL databases. You've been using them for years, you've learned how to make them work well enough for you, and you know that learning MongoDB will require you to change your mindset. Is it really worth the effort?

Yes!

In this post, we'll examine the top four reasons why you should use MongoDB:

This article is based on a presentation I gave at MongoDB World and MongoDB.local Houston entitled "From SQL to NoSQL: Changing Your Mindset."

If you prefer videos over articles, check out the recording. Slides are available here.

#Scale Cheaper

You can scale cheaper with MongoDB. Why?

Let's begin by talking about scaling SQL databases. Typically, SQL databases scale vertically-when a database becomes too big for its server, it is migrated to a larger server.

Vertical scaling
Vertical scaling by migrating to larger servers

A few key problems arise with vertical scaling:

  • Large servers tend to be more expensive than two smaller servers with the same total capacity.
  • Large servers may not be available due to cost limitations, cloud provider limitations, or technology limitations (a server the size you need may not exist).
  • Migrating to a larger server may require application downtime.

When you use MongoDB, you have the flexibility to scale horizontally through sharding. Sharding is a method for distributing data across multiple servers. When your database exceeds the capacity of its current server, you can begin sharding and split it over two servers. As your database continues to grow, you can continue to add more servers. The advantage is that these new servers don't need to be big, expensive machines-they can be cheaper, commodity hardware. Plus, no downtime is required.

Horizontal scaling
Horizonal scaling by adding more commodity servers

#Query Faster

Your queries will typically be faster with MongoDB. Let's examine why.

Even in our simple example in the previous post where we modeled Leslie's data in SQL, we saw that her information was spread across three tables. Whenever we want to query for Leslie's information, we'll need to join three tables together.

In these three small tables, the join will be very fast. However, as the tables grow and our queries become more complex, joining tables together becomes very expensive.

Representation of joining tables in a SQL database

Recall our rule of thumb when modeling data in MongoDB: data that is accessed together should be stored together. When you follow this rule of thumb, most queries will not require you to join any data together.

Continuing with our earlier example, if we want to retrieve Leslie's information from MongoDB, we can simply query for a single document in the Users collection. As a result, our query will be very fast.

As our documents and collections grow larger, we don't have to worry about our queries slowing down as long as we are using indexes and continue following our rule of thumb: data that is accessed together should be stored together.

Representation of a MongoDB query with no joins

#Pivot Easier

Requirements change. Sometimes the changes are simple and require only a few tweaks to the user interface. But sometimes changes go all the way down to the database.

In the previous post in this series, we discovered—after implementing our application—that we needed to store information about Lauren's school. Let's take a look at this example a little more closely.

To add a new school column in our SQL database, we're going to have to alter the Users table. Executing the Alter Table command could take a couple of hours depending on how much data is in the table. The performance of our application could be decreased while the table is being altered, and we may need to schedule downtime for our application.

Alter Table command

Now let's examine how we can do something similar in MongoDB. When our requirements change and we need to begin storing the name of a user's school in a User document, we can simply begin doing so. We can choose if and when to update existing documents in the collection.

If we had implemented schema validation, we would have the option of applying the validation to all inserts and updates or only to inserts and updates to documents that already meet the schema requirements. We would also have the choice of throwing an error or a warning if a validation rule is violated.

With MongoDB, you can easily change the shape of your data as your app evolves.

Change the shape of your data in MongoDB without executing an Alter Table command

#Program Faster

To be honest with you, this advantage is one of the biggest surprises to me. I figured that it didn't matter what you used as your backend database—the code that interacts with it would be basically the same. I was wrong.

Ben looks completely shocked
MFW I realized how much easier it is to code with MongoDB.

MongoDB documents map to data structures in most popular programming languages. This sounds like such a simple thing, but it makes a humongous difference when you're writing code.

A friend encouraged me to test this out, so I did. I implemented the code to retrieve and update user profile information. My code has some simplifications in it to enable me to focus on the interactions with the database rather than the user interface. I also limited the user profile information to just contact information and hobbies.

Below is a comparison of my implementation using MySQL and MongoDB.

I wrote the code in Python, but, don't worry if you're not familiar with Python, I'll walk you through it step by step. The concepts will be applicable no matter what your programming language of choice is.

#Connect to the Databases

Let's begin with the typical top-of-the-file stuff. We'll import what we need, connect to the database, and declare our variables. I'm going to simplify things by hardcoding the User ID of the user whose profile we will be retrieving rather than pulling it dynamically from the frontend code.

MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
import mysql.connector # CONNECT TO THE DB mydb = mysql.connector.connect( host="localhost", user="root", passwd="rootroot", database="CityHall" ) mycursor = mydb.cursor(dictionary=True) # THE ID OF THE USER WHOSE PROFILE WE WILL BE RETRIEVING AND UPDATING userId = 1

We'll pass the dictionary=True option when we create the cursor so that each row will be returned as a dictionary.

MongoDB

1
2
3
4
5
6
7
8
9
10
import pymongo from pymongo import MongoClient # CONNECT TO THE DB client = MongoClient() client = pymongo.MongoClient("mongodb+srv://root:rootroot@mycluster.mongodb.net/test?retryWrites=true&w=majority") db = client.CityHall # THE ID OF THE USER WHOSE PROFILE WE WILL BE RETRIEVING AND UPDATING userId = 1

So far, the code is pretty much the same.

#Get the User's Profile Information

Now that we have our database connections ready, let's use them to retrieve our user profile information. We'll store the profile information in a Python Dictionary. Dictionaries are a common data structure in Python and provide an easy way to work with your data.

Let's begin by implementing the code for MySQL.

Since the user profile information is spread across the Users table and the Hobbies table, we'll need to join them in our query. We can use prepared statements to ensure our data stays safe.

MySQL

1
2
3
4
sql = "SELECT * FROM Users LEFT JOIN Hobbies ON Users.ID = Hobbies.user_id WHERE Users.id=%s" values = (userId,) my cursor.execute(sql, values) user = mycursor.fetchone()

When we execute the query, a result is returned for every user/hobby combination. When we call fetchone(), we get a dictionary like the following

1
{u'city': u'Pawnee', u'first_name': u'Leslie', u'last_name': u'Yepp', u'user_id': 1, u'school': None, u'longitude': -86.5366, u'cell': u'8125552344', u'latitude': 39.1703, u'hobby': u'scrapbooking', u'ID': 10}

Because we joined the Users and the Hobbies tables, we have a result for each hobby this user has. To retrieve all of the hobbies, we need to iterate the cursor. We'll append each hobby to a new hobbies array and then add the hobbies array to our user dictionary.

MySQL

1
2
3
4
5
6
7
8
hobbies = [] if (user["hobby"]): hobbies.append(user["hobby"]) del user["hobby"] del user["ID"] for result in mycursor: hobbies.append(result["hobby"]) user["hobbies"] = hobbies

Now let's implement that same functionality for MongoDB.

Since we stored all of the user profile information in the User document, we don't need to do any joins. We can simply retrieve a single document in our collection.

Here is where the big advantage that MongoDB documents map to data structures in most popular programming languages comes in. I don't have to do any work to get my data into an easy-to-work-with Python Dictionary. MongoDB gives me all of the results in a Python Dictionary automatically.

MongoDB

1
user = db['Users'].find_one({"_id": userId})

And that's it—we're done. What took us 12 lines for MySQL, we were able to implement in 1 line for MongoDB.

Our user dictionaries are now pretty similar in both pieces of code.

MySQL

1
2
3
4
5
6
7
8
9
10
11
{ 'city': 'Pawnee', 'first_name': 'Leslie', 'last_name': 'Yepp', 'school': None, 'cell': '8125552344', 'latitude': 39.1703, 'longitude': -86.5366,3 'hobbies': ['scrapbooking', 'eating waffles', 'working'], 'user_id': 1 }

MongoDB

1
2
3
4
5
6
7
8
9
{ 'city': 'Pawnee', 'first_name': 'Leslie', 'last_name': 'Yepp', 'cell': '8125552344', 'location': [-86.536632, 39.170344], 'hobbies': ['scrapbooking', 'eating waffles', 'working'], '_id': 1 }

Now that we have retrieved the user's profile information, we'd likely send that information up the stack to the frontend UI code.

#Update the User's Profile Information

When Leslie views her profile information in our application, she may discover she needs to update her profile information. The frontend UI code would send that updated information in a Python dictionary to the Python files we've been writing.

To simulate Leslie updating her profile information, we'll manually update the Python dictionary ourselves for both MySQL and MongoDB.

MySQL:

1
2
3
4
5
6
user.update( { "city": "Washington, DC", "latitude": 38.897760, "longitude": -77.036809, "hobbies": ["scrapbooking", "eating waffles", "signing bills"] } )

MongoDB:

1
2
3
4
5
user.update( { "city": "Washington, DC", "location": [-77.036809, 38.897760], "hobbies": ["scrapbooking", "eating waffles", "signing bills"] } )

Now that our user dictionary is updated, let's push the updated information to our databases.

Let's begin with MySQL. First, we need to update the information that is stored in the Users table.

MySQL

1
2
3
4
sql = "UPDATE Users SET first_name=%s, last_name=%s, cell=%s, city=%s, latitude=%s, longitude=%s, school=%s WHERE (ID=%s)" values = (user["first_name"], user["last_name"], user["cell"], user["city"], user["latitude"], user["longitude"], user["school"], userId) mycursor.execute(sql, values) mydb.commit()

Second, we need to update our hobbies. For simplicity, we'll delete any existing hobbies in the Hobbies table for this user and then we'll insert the new hobbies into the Hobbies table.

MySQL

1
2
3
4
5
6
7
8
9
10
11
12
sql = "DELETE FROM Hobbies WHERE user_id=%s" values = (userId,) mycursor.execute(sql, values) mydb.commit() if(len(user["hobbies"]) > 0): sql = "INSERT INTO Hobbies (user_id, hobby) VALUES (%s, %s)" values = [] for hobby in user["hobbies"]: values.append((userId, hobby)) mycursor.executemany(sql,values) mydb.commit()

Now let's update the user profile information in MongoDB. Since the user's profile information is stored in a single document, we only have to do a single update. Once again we will benefit from MongoDB documents mapping to data structures in most popular programming languages. We can send our user Python dictionary when we call update_one(), which significantly simplifies our code.

MongoDB

1
result = db['Users'].update_one({"_id": userId}, {"$set": user})

What took us 15 lines for MySQL, we were able to implement in 1 line for MongoDB.

#Summary of Programming Faster

In this example, we wrote 27 lines of code to interact with our data in MySQL and 2 lines of code to interact with our data in MongoDB. While fewer lines of code is not always indicative of better code, in this case, we can probably agree that fewer lines of code will likely lead to easier maintenance and fewer bugs.

The examples above were relatively simple with small queries. Imagine how much bigger the difference would be for larger, more complex queries.

MongoDB documents mapping to data structures in most popular programming languages can be a huge advantage in terms of time to write, debug, and maintain code.

The code above was written in Python and leveraged the Python MongoDB Driver. For a complete list of all of the programming languages that have MongoDB drivers, visit the MongoDB Manual.

If you'd like to grab a copy of the code in the examples above, visit my GitHub repo.

#Wrap Up

In this post, we discussed the top four reasons why you should use MongoDB:

Be on the lookout for the final post in this series where I'll discuss the top three things you need to know as you move from SQL to MongoDB.

More from this series

SQL to MongoDB
  • Mapping Terms and Concepts from SQL to MongoDB
  • The Top 4 Reasons Why You Should Use MongoDB
  • 3 Things to Know When You Switch from SQL to MongoDB
MongoDB Icon
  • Developer Hub
  • Documentation
  • University
  • Community Forums

© MongoDB, Inc.