When not to use MongoDB and why?

Updated: February 1, 2024 By: Guest Contributor Post a comment

Introduction

MongoDB is a popular NoSQL database widely used for its flexibility, scalability, and performance. However, it is essential to know that it might not always be the ideal choice for all applications. In this tutorial, we will explore the scenarios where MongoDB would not be the go-to database, supported by relevant code examples.

Understanding MongoDB’s Limitations

MongoDB shines when you need schema flexibility, quick iterations, or working with large amounts of data with a loose structure. Nevertheless, there are certain limitations that might urge developers to consider alternatives:

  • Stiff transactional requirements
  • Need for complex joins
  • Consistency over availability
  • Strict data integrity

Complex Transactions with ACID Compliance

While MongoDB has introduced multi-document transactions, it’s still unsuitable for complex and high-volume ACID-compliant transactions. Relational databases like PostgreSQL are more equipped for this task. Consider the following example:

db.orders.insertOne({
 _id: 'order123',
 cust_id: 'customer567',
 amount: 100,
 status: 'pending'
});

db.transactions.insertOne({
 order_id: 'order123',
 action: 'charge',
 amount: 100,
 status: 'pending'
});

This code segment represents the creation of an order and a linked transaction. If these operations needed to be in a strict transactional order, with rollbacks in case of failures, a relational database would handle this more gracefully.

When Joins and Data Relationships are Fundamental

Suppose you have an application resembling an extensive inventory system. Natively, MongoDB doesn’t support joins as efficiently as SQL databases:

db.products.find({});
db.suppliers.find({});

In MongoDB, you would need to manually merge these two queries programmatically, which is not as efficient or straightforward as a SQL JOIN operation:

SELECT *
FROM products
INNER JOIN suppliers ON products.supplier_id = suppliers.id;

This example clearly illustrates how a simple SQL join can combine related data, an area where MongoDB lags behind.

Strong Consistency Requirements

Applications that require strong consistency over availability and cannot tolerate eventual consistency should be cautious. When data integrity is non-negotiable, such as in banking systems, alternatives like MySQL may be more suitable:

UPDATE accounts SET balance = balance - 100 WHERE account_id = 123;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 456;

Here, both the update statements need to run as one atomic operation, which is something relational databases guarantee better than MongoDB.

Data Integrity and Schema Validation

In systems where strict data validation is required, such as medical records, MongoDB’s schema-less nature might introduce risks:

db.medicalRecords.insertOne({
 patient_id: 'patient123',
 diagnosis: ['diabetes', 'hypertension'],
 treatments: null
});

MongoDB’s flexible schema can allow for unforeseen errors and lack of constraints that a relational database would prevent with its structured schema design.

Code Examples of Unsuitable Use-Cases

Let’s illustrate further with some advanced code examples that shed light on MongoDB’s limitations for specific tasks:

Implementing SQL-Like Transactions

MongoDB added the ‘session.startTransaction()’ functionality, but it’s not the native behavior and can be complex:

const session = db.getMongo().startSession();
session.startTransaction();
try {
 db.collection('inventory').updateOne({...}, {...}, { session });
 db.collection('sales').insertOne({...}, { session });
 session.commitTransaction();
} catch (error) {
 session.abortTransaction();
}

This code snippet shows how we can use transactions in MongoDB, but it’s cumbersome compared to the default behavior in SQL databases.

Modeling Highly Normalized Data Structures

Traditionally, MongoDB is not designed for highly normalized data structures. This complexity becomes evident when attempting to emulate this structure:

db.customers.insertOne({ cust_id: '123', orders: ['order1', 'order2'] });
db.orders.insertMany([
 { _id: 'order1', product: 'product1', quantity: 10 },
 { _id: 'order2', product: 'product2', quantity: 5 }
]);

In MongoDB, you would need to fetch and link this data with additional logic, unlike SQL’s natural support for normalized data.

Alternative Solutions

For each of these use-cases, SQL databases offer built-in solutions:

  • ACID-compliant transactions
  • Effortless joins with multiple tables
  • Enforced foreign key constraints
  • Strong data consistency models

Conclusion

In summary, MongoDB is a powerful tool, but it is crucial to evaluate its capabilities against your project’s requirements. When your application involves complex transactions, emphasis on joins, strong consistency, or rigid data integrity, you may want to look towards traditional SQL databases to avoid costly compromises.