Why the relational model cracked at web scale β and the four NoSQL families that replaced it.
You can now design a normalised schema, write joins, and reason about transactions. That toolkit solves a large share of business problems β and this module is not here to take it away.
For structured, transactional, single-server workloads, relational databases remain the correct default. Banks still run on them.
A second toolkit for workloads where the relational model is a poor fit β and the judgement to tell the two apart.
| Pressure | What Happened | Why SQL Struggled |
|---|---|---|
| Volume | Datasets outgrew the largest single server available | The relational model assumes one authoritative machine |
| Schema churn | Product shape changed weekly, not yearly | Every change is an ALTER TABLE on a live system |
| Impedance mismatch | Apps work in nested objects; tables are flat | Shred on write, join on read β forever |
Every product type has a different set of attributes. In a relational schema you get three unattractive options:
| Option | Cost |
|---|---|
| One wide table | Hundreds of mostly-NULL columns; new type = schema migration |
| Table per type | "All products under βΉ2,000" becomes a UNION across dozens of tables |
| Entity-Attribute-Value | Everything becomes a string; the database can no longer validate or index |
{
name: "Priya Sharma",
addresses: [
{ type: "home", city: "Delhi" },
{ type: "work", city: "Gurgaon" }
]
}
customers(id, name)
addresses(id, customer_id,
type, city, pin)
-- plus a JOIN on every read
Buy a bigger machine. Simple, no app changes, joins and transactions stay easy.
Limits: cost rises faster than capacity, a hard physical ceiling, single point of failure.
Add commodity machines, spread the data. Capacity grows near-linearly; one node can die safely.
Limits: data is now distributed β joins, transactions and consistency get genuinely hard.
Sharding: split the data by key β customers AβM on Server 1, NβZ on Server 2. That is what makes horizontal scale work.
Now run SELECT ... FROM orders JOIN customers. The orders are on Server 1, the matching customers on Server 2. The database must ship data across the network mid-query.
Rather than make distributed joins fast β close to impossible β restructure the data so the join is never needed. Store the order with its customer details embedded. You accept duplication to buy horizontal scale.
| Property | Meaning | If You Lose It |
|---|---|---|
| C Consistency | Every read returns the latest write | Users briefly see different answers |
| A Availability | Every request gets a response | Some requests fail or time out |
| P Partition tolerance | Works when the network splits | A network fault downs everything |
You do not choose whether to have partitions β networks fail. P is mandatory. The real choice is what to do during a split: refuse requests (CP) or answer and reconcile later (AP).
Bank transfer. Refuse the transaction rather than risk double-spending a balance.
Customer sees: "Temporarily unavailable."
Systems: MongoDB, HBase, Redis Cluster
Shopping cart. Accept the item now, reconcile versions when the network heals.
Customer sees: a working site.
Systems: Cassandra, DynamoDB, CouchDB
| ACID | BASE | |
|---|---|---|
| Promise | All-or-nothing; never in between | Always answers; replicas converge shortly |
| Optimises | Correctness | Availability and scale |
| Right for | Payments, ledgers, inventory, bookings | Feeds, recommendations, analytics, sessions |
| Wrong for | Global write scale | Anything where staleness costs money |
MongoDB has had multi-document ACID transactions since v4.0 (2018). The modern skill is not picking a camp β it is knowing which guarantee each operation needs.
A giant dictionary. Sub-millisecond reads, but you can only fetch by key.
Redis, DynamoDB Β· caching, sessions, counters
Structured JSON records. Query and index inside the record.
MongoDB, Couchbase Β· catalogues, profiles, bookings
Stored by column. Enormous write throughput; rigid query patterns.
Cassandra, HBase Β· time-series, telemetry
Relationships are the data. Traversal is constant-time at any scale.
Neo4j, Neptune Β· fraud rings, recommendations
{
"_id": "CNR3000142",
"status": "Completed",
"vehicle_type": "Go Sedan",
"route": { "pickup": "Connaught Place", "drop": "Aerocity" },
"booking_value": 412.50,
"ride_distance": 18.4,
"ratings": { "driver": 4.6, "customer": 4.8 },
"payment_method": "UPI"
}
No joins. No NULL columns for the fields this booking does not use. The stored shape is the shape the application already works with.
| Family | Query By | Best At | Avoid When |
|---|---|---|---|
| Key-Value | Key only | Raw speed, caching | You must search by value |
| Document | Any field | Flexible, evolving records | Heavy multi-entity joins |
| Column-Family | Partition key | Massive write volume | Ad-hoc exploration |
| Graph | Traversal | Deep relationships | Bulk aggregation |
| Relational | SQL | Transactions, reporting | Petabyte horizontal scale |
| # | Scenario |
|---|---|
| 1 | A ride-hailing firm stores 150,000 bookings a year. Fields differ by product line, and analysts need ad-hoc queries on any attribute. |
| 2 | An e-commerce site shows a live "trending in the last 5 minutes" strip on every page load. |
| 3 | An insurer wants to find rings of claimants sharing addresses, phones and repair garages. |
| Myth | Reality |
|---|---|
| "NoSQL means no SQL" | It means not only SQL. Many NoSQL systems ship SQL-like languages. |
| "There is no schema" | The schema moves into the application β it still exists. |
| "No transactions" | MongoDB has had ACID transactions since 4.0 (2018). |
| "Always faster" | Only for its intended access pattern. A bad document model loses to a good index. |
| "It replaces relational" | Polyglot persistence β mature firms run several, each doing its best job. |
Everything from Lecture 12 onward needs this. The M0 tier is free forever, needs no credit card, and gives 512 MB.
BDMA β Build a Cluster β M0 Freeap-south-1 (Mumbai) for lowest latency in Indiabdma_student with readWriteAnyDatabase0.0.0.0/0 (teaching cluster only)It contains a live password. Scanners find exposed Atlas credentials within minutes of a public push. Keep it in a local .env and .gitignore that file.