MongoDB
SQL vs NoSQL Databases
One of the most important decisions you make when building any application is which type of database to use. SQL and NoSQL represent two fundamentally different philosophies about how data should be stored, structured, and queried. Neither is universally better — each solves a different set of problems. Understanding the distinction deeply will help you make the right choice every time.
This lesson covers the architectural differences, when to use each, real-world examples of both in production, and the common misconceptions that trip up developers when making the choice.
What is a SQL Database?
SQL (Structured Query Language) databases — also called relational databases — organise data into tables made of rows and columns. Every table has a fixed schema: you define the columns upfront, and every row must conform to that structure. Relationships between tables are established through foreign keys, and data is queried using SQL — a standardised, declarative language.
Why it exists: the relational model was designed to eliminate data redundancy, ensure consistency through constraints, and make it possible to ask complex questions about interconnected data through joins — all with a single standardised language.
Real-world use: banking systems, payroll, ERP software, airline reservations, e-commerce order management — anywhere data integrity, complex relationships, and consistency are non-negotiable.
# SQL database — data lives in structured tables
# users table
# | id | name | email | age |
# |----|---------|---------------------|-----|
# | 1 | Alice | alice@example.com | 30 |
# | 2 | Bob | bob@example.com | 25 |
# orders table — references users via user_id (foreign key)
# | id | user_id | product | amount |
# |----|---------|------------|--------|
# | 1 | 1 | Laptop | 999.99 |
# | 2 | 1 | Mouse | 29.99 |
# | 3 | 2 | Keyboard | 79.99 |
# SQL query — join tables to answer "what did Alice buy?"
query = """
SELECT users.name, orders.product, orders.amount
FROM users
JOIN orders ON users.id = orders.user_id
WHERE users.name = 'Alice'
"""
print(query)FROM users
JOIN orders ON users.id = orders.user_id
WHERE users.name = 'Alice'
- Tables have a strict schema — every row must have the same columns
- Relationships are enforced at the database level through foreign keys
- SQL is standardised — the same query syntax works across MySQL, PostgreSQL, Oracle
- ACID compliance is built in — transactions are reliable and consistent
What is a NoSQL Database?
NoSQL (Not Only SQL) databases abandon the rigid table structure in favour of flexible data models better suited to modern applications. Rather than rows in tables, data might be stored as JSON documents, key-value pairs, wide columns, or graph nodes. The schema is flexible — different records can have different fields.
Why it exists: the web-scale explosion of the 2000s revealed that relational databases struggled with three challenges: enormous data volumes, variable data structures, and the need to scale horizontally across many cheap servers rather than vertically on one expensive machine.
Real-world use: user profiles (MongoDB), session caching (Redis), activity feeds (Cassandra), recommendation graphs (Neo4j) — any scenario where flexibility, scale, or speed outweighs the need for rigid structure.
# NoSQL database (MongoDB) — data lives in flexible documents
user_alice = {
"_id": "user_001",
"name": "Alice",
"email": "alice@example.com",
"age": 30,
"address": { # nested object — no separate table needed
"city": "London",
"postcode": "EC1A 1BB"
},
"orders": [ # embedded array — no JOIN needed
{"product": "Laptop", "amount": 999.99},
{"product": "Mouse", "amount": 29.99}
],
"preferences": ["dark_mode", "notifications_off"]
}
user_bob = {
"_id": "user_002",
"name": "Bob",
"email": "bob@example.com"
# Bob has no address, no orders, no preferences — that's fine in NoSQL
}
print(user_alice["name"], "has", len(user_alice["orders"]), "orders")
print(user_bob["name"], "has no orders field — valid in NoSQL")Bob has no orders field — valid in NoSQL
- Documents are self-contained — related data is embedded rather than spread across tables
- Different documents in the same collection can have completely different fields
- No JOINs needed for data that belongs together — it is stored together
- Scales horizontally — add more servers to handle more data and traffic
Head-to-Head Comparison
| Factor | SQL | NoSQL |
|---|---|---|
| Data model | Tables with rows and columns | Documents, key-value, graphs, columns |
| Schema | Fixed — defined upfront, hard to change | Flexible — evolves with the application |
| Query language | SQL — standardised across vendors | Varies per database (MQL, Redis commands…) |
| Scaling | Vertical (bigger server) | Horizontal (more servers — sharding) |
| ACID compliance | Full ACID by default | Varies — MongoDB supports ACID since v4.0 |
| Joins | Native, powerful multi-table joins | Limited — data often embedded to avoid joins |
| Relationships | Enforced at DB level (foreign keys) | Managed at application level |
| Best for | Complex relationships, strict consistency | Flexibility, speed, large scale, varied data |
When to Choose SQL
SQL databases are the right tool when your data is well-structured, your relationships are complex, and data integrity is critical.
- Financial systems — bank transactions, accounting ledgers, payroll. ACID compliance is non-negotiable.
- E-commerce order management — orders, line items, inventory, invoices. Complex relationships between many entities.
- HR and ERP systems — employees, departments, roles, contracts. Highly relational, mature reporting needs.
- Any system where the schema is stable and well-understood from the start.
- Applications that require complex multi-table queries and aggregations.
When to Choose NoSQL
NoSQL databases shine when your data structure is variable, your scale is massive, or your development speed needs to be high.
- User profiles and content — different users have different attributes, preferences, and settings. A flexible document fits perfectly.
- Product catalogues — a shoe has size and colour; a laptop has RAM and CPU; a book has ISBN and author. Different fields per product type.
- Real-time applications — chat messages, activity feeds, notifications. High write throughput, simple lookups.
- Rapid prototyping — when the data model is evolving and you cannot afford to write migrations for every schema change.
- Applications needing horizontal scale — MongoDB can distribute data across dozens of servers automatically.
The "NoSQL means no structure" Misconception
A common mistake is assuming NoSQL means chaotic, unstructured data. In practice, well-designed MongoDB applications have very deliberate data models — they just enforce structure at the application level rather than the database level. MongoDB even supports JSON Schema validation to enforce rules on documents if you need that guarantee.
# MongoDB JSON Schema validation — enforcing structure when needed
validator = {
"$jsonSchema": {
"bsonType": "object",
"required": ["name", "email", "age"], # these fields must exist
"properties": {
"name": {"bsonType": "string", "description": "must be a string"},
"email": {"bsonType": "string", "pattern": "^.+@.+$"},
"age": {"bsonType": "int", "minimum": 0, "maximum": 130}
}
}
}
# Apply when creating a collection:
# db.createCollection("users", {"validator": validator})
# Now MongoDB will REJECT any document missing name, email, or age
print("Validator defined — MongoDB rejects documents that fail the schema rules.")- MongoDB's schema flexibility is a choice, not a limitation — you can enforce strict rules when needed
- JSON Schema validation rejects invalid documents at write time — catching errors before they pollute your data
- The sweet spot: flexible where the data varies, strict where consistency matters
NewSQL — The Best of Both Worlds
A newer category called NewSQL attempts to combine SQL's ACID guarantees and relational model with NoSQL's horizontal scalability. Examples include Google Spanner, CockroachDB, and PlanetScale. These are worth knowing about as the landscape continues to evolve.
Summary Table
| Concept | SQL | NoSQL (MongoDB) |
|---|---|---|
| Unit of storage | Row in a table | Document in a collection |
| Schema | Fixed, enforced by DB | Flexible, enforced by app (or optional validation) |
| Scaling direction | Vertical | Horizontal |
| Related data | Joined across tables | Embedded in document |
| Ideal use case | Financial, relational, strict integrity | Profiles, catalogues, real-time, rapid dev |
Practice Questions
Practice 1. What is the main structural difference between how SQL and NoSQL databases store data?
Practice 2. What are the three challenges that drove the rise of NoSQL databases in the 2000s?
Practice 3. In MongoDB, what feature can you use to enforce strict field requirements on documents?
Practice 4. Which type of database is best suited for a product catalogue where different products have different attributes?
Practice 5. What is the difference between vertical and horizontal scaling?
Quiz
Quiz 1. In a SQL database, what enforces relationships between tables?
Quiz 2. Since which version of MongoDB does it support multi-document ACID transactions?
Quiz 3. What is the NoSQL equivalent of a SQL table?
Quiz 4. Which category of database combines SQL's ACID guarantees with NoSQL's horizontal scalability?
Quiz 5. Why do NoSQL databases avoid JOINs?
Next up — What is MongoDB: origin, core design principles, and what makes it the world's most popular NoSQL database.