System Design Β· Chapter 09

Choosing where your data lives

There's no "best" database β€” only the right one for a use case. This chapter builds the vocabulary to choose: the shape of your data, the consistency you can afford, and the specialized stores that each win at exactly one job.

🧭
How to read this

The chapter builds in three arcs. First, the two families β€” relational and NoSQL β€” and the honest truth about their performance. Second, the distributed-systems concepts that decide everything downstream: consistency models and the CAP theorem. Third, a tour of the specialized NoSQL stores, each with a "when to pick it" and real-world users. Anything marked [+] is context I added; everything else is rewritten from the nineteen teaching lessons.

01

Data comes in four shapes

A database is the component that persists data β€” and the shape of that data drives every choice that follows. Before picking a store, classify what you're storing:

Type What it is Example
Structured Conforms to a strict schema, stored normalized; easiest to work with β€” no prep needed. Managed by a query language like SQL. A customer row: id (int), name (string, length limit), age (int).
Unstructured No definite structure; heterogeneous. Must pass through a data-prep stage before analytics algorithms can run on it. Text, images, video, PDFs, blobs, machine-generated data streaming from IoT devices, sensors, social networks.
Semi-structured A mix of the two, held in transport formats and handled per business needs. XML, JSON.
User state The record of a user's activity on a site. Persisting it improves UX and conversion, and lets users resume where they left off. Categories browsed, sorts applied, items added to a wishlist.
02

Relational databases: relationships and ACID

A relational database stores data with relationships in tables of rows and columns, queried with SQL. It's the most widely used type in web development (MySQL, PostgreSQL, SQL Server, MariaDB, Amazon Aurora, Google Cloud SQL). It does three things exceptionally well.

Relationships

It models one-to-one, one-to-many, many-to-many, and many-to-one links. Buy five books from an online store and your customer id C1 links to books B1–B5 β€” a one-to-many relationship. One row in the customers table maps to many rows in the products table, and pulling C1 tells you exactly what they bought.

Normalization & consistency

Data is stored normalized β€” each entity lives in exactly one place, in its simplest atomic form, not spread across the database. To update it later, you change one row, not many scattered copies, which keeps the data consistent.

ACID transactions

ACID = Atomicity, Consistency, Isolation, Durability. A transaction executes completely without affecting other processes, and if anything goes wrong mid-way β€” even a minor failure β€” the whole operation rolls back. The system moves from a consistent, durable State A to a consistent, durable State B with no middle state; on failure it always returns to State A.

State A consistent transaction State B consistent rollback on failure
Figure 1 β€” An ACID transaction: the system is only ever in consistent State A or State B; any failure rolls all the way back to A. [+] State-machine view of the lesson's description.

Pick relational when you need strong consistency, transactions, or relationships β€” stock trading, banking (anything with money), and relationship-heavy social apps. Bonus: a huge community of seasoned engineers, and it's battle-tested. Facebook uses a relational database as its main user-facing DB.

03

NoSQL: built to scale on clusters

NoSQL databases have no SQL β€” they're more like JSON-based stores built for Web 2.0 and high-frequency reads and writes (micro-blogging, real-time sports apps, massive multiplayer games). They exist to solve the one thing relational databases struggle with: scaling.

Scaling a relational DB isn't trivial β€” it must be sharded and replicated to run on a cluster, needing careful planning, human intervention, and skill. NoSQL databases instead add server nodes on the fly and scale with minimal human intervention, running intelligently on clusters with self-healing nodes. The trade-off they accepted to get there: they gave up strong consistency and global ACID transactions, landing on eventual consistency instead.

Pros Cons
NoSQL Scales on the fly; developer-friendly with a gentler learning curve; schemaless and flexible; no joins or relationships to manage; fetch by key is O(1), making it fast and simple. Inconsistency risk (un-normalized data must be updated in many places); no global ACID β€” a few claim ACID but only within a limited entity hierarchy or small region where nodes can be locked.

Pick NoSQL when you need to handle a large volume of read/writes and big data with low latency, want data-model flexibility early in development, can accept eventual over strong consistency, or are running analytics on massive data influx. Popular: MongoDB, Redis, Neo4J, Cassandra, Memcached.

🐦
The Twitter-like-count example

When a celebrity's tweet blows up, does it matter if the like count reads 5,000,250 instead of 5,000,500 for a moment? No β€” so eventual consistency is fine. You see this on YouTube: a video showing 10 views but 15 likes. The views are simply inconsistent for a short while, not lost.

04

Is NoSQL faster than SQL? No.

From a benchmarking standpoint, relational and non-relational databases are equally performant. Performance comes from how you design the system, not the technology label β€” application architecture, database design, bottlenecks, and network latency decide it. Pile on joins in a relational DB and responses slow; strip the complex relationships and joins, and a relational DB is as quick as a NoSQL one.

πŸ“’
So why do popular stacks always reach for NoSQL?

Stacks like MEAN (MongoDB, Express, Angular/React, Node) cover most standard use cases, and there are commercial reasons plus a flood of tutorials that make them easy for beginners to grab β€” rather than researching the fitting technology. Don't follow the hype; pick for your use case. And note: a well-designed SQL store beats a poorly-designed NoSQL one every time. Facebook runs MySQL for its social graph; Quora uses MySQL efficiently by partitioning at the application level.

And you don't have to choose just one β€” every large-scale service mixes both. That's polyglot persistence, next.

05

Polyglot persistence & the multi-model shortcut

Polyglot persistence means using several distinct persistence technologies together in one application to satisfy its different needs. Design a social network like Facebook and each feature pulls a different store:

Application Relational relations, payments Key-value cache, sessions Wide-column analytics Graph recommendations Document search (Elastic) Key-value distributed state
Figure 2 β€” Polyglot persistence: one app, many specialized stores β€” relational for payments, key-value for cache, wide-column for analytics, graph for recommendations, document for search. Original diagram after Illustration 1.58.

The catch: operational complexity β€” making all these technologies work together in a distributed environment takes real effort to build, manage, and monitor. The shortcut is a multi-model database: a single system that supports multiple data models (graph, document, relational) through one API, cutting the need to run several persistence technologies. Popular multi-model stores: ArangoDB, CosmosDB, OrientDB, Couchbase.

06

Eventual vs. strong consistency

These two models are the heart of distributed data, and the tweet-like-counter makes them concrete. Picture a microblogging site with database nodes in data-center zones across Asia, America, and Europe.

Eventual consistency (optimistic replication)

A user in Japan likes a tweet, pushing the count 100 β†’ 101. At the same instant a user in America still sees 100 β€” the new value needs time to travel across continents and update those nodes. Refresh a few seconds later and it reads 101. The data was briefly inconsistent but eventually became consistent. The payoff: nodes can be added on the fly, no node needs to be locked, and millions of users can write concurrently β€” making the system highly available. Fits when accuracy doesn't need to be instant (like counts, live-viewer counts, analytics).

Strong consistency

Every node worldwide holds the same value at all times. The only way to do it is to lock the nodes during an update: when Japan updates 100 β†’ 101, all nodes are locked, the value replicates globally, consensus is reached, then locks lift. Only one user can update at a time; others wait. Fine for a stock-market app where users must never see different prices β€” but it hits scalability and availability. This locking is what enables ACID transactions.

Eventual 101 Japan 100 America 100 Europe all writable, differ briefly Strong 101 updating πŸ”’101 locked πŸ”’101 locked locked until consensus
Figure 3 β€” Eventual consistency lets regional nodes diverge briefly while staying writable; strong consistency locks nodes so all agree at all times. Original diagram after Illustrations 1.60–1.61.
07

The CAP theorem: pick two, really pick one

CAP = Consistency, Availability, Partition tolerance. Partition tolerance means fault tolerance β€” the system keeps working even when some nodes go offline. The common phrasing is "pick two of three," but the course offers a clearer framing:

πŸ”€
The clearer statement

When a network failure happens and some nodes are down, you must choose between availability and consistency.

Which you pick depends on the use case. You can't have both at once β€” nodes spread around the globe take time to reach consensus, and zero latency is impossible.

Network partition some nodes down Availability writable Β· may serve stale Consistency locked Β· always correct
Figure 4 β€” CAP in practice: a partition forces the choice between staying available (risking stale reads) and staying consistent (locking for correctness). [+] Decision-fork view of the lesson.
08

Document databases: JSON, flexible schema

Document-oriented databases are the leading NoSQL type, storing semi-structured data as independent documents in a JSON-like format. The data model mirrors application-code objects, making storage and querying natural for developers, and it pairs well with Agile because a flexible schema is easy to evolve. Popular: MongoDB, CouchDB, OrientDB, Google Cloud Datastore, Amazon DocumentDB.

Pick a document store when you're working with semi-structured data and a schema that changes often, you're unsure of the schema up front, or you need to scale fast and stay highly available. Being NoSQL, it gives horizontal scalability and fast reads/writes for CRUD use cases with little relational logic. Typical uses: real-time feeds, live sports apps, product catalogs, inventory management, user comments, web-based multiplayer games. Real-world: SEGA (MongoDB for mobile gamers), Wix (MongoDB to host sites).

09

Graph databases: relationships as first-class edges

Graph databases store entities as nodes and relationships as edges β€” and because those edges are persisted directly, traversing them needs no join-time computation. That's why they're fast: a relational DB computes relationships at query time via joins; a graph DB just fetches the stored edges. Neo4J is the popular example.

Alice Bob Carol NYC Cafe friend friend lives_in lives_in ate_at
Figure 5 β€” A graph: people as nodes, "friend"/"lives_in"/"ate_at" as stored edges β€” relationships fetched, never computed. Original diagram after Illustration 1.64.

Graphs are everywhere. Google Maps is one big graph β€” cities/places as nodes, roads as edges β€” and uses shortest-path algorithms (Dijkstra, Bellman-Ford, A*, Floyd–Warshall, Johnson's, Viterbi) to route; Uber and Ola use routing algorithms over it. Flight networks work the same. Google's PageRank treats web pages as weighted nodes and links as edges, ranking higher-weight (more authoritative) pages first.

Pick a graph DB when you need to store complex relationships: social/knowledge/network graphs, AI apps, recommendation engines, fraud analysis, genetic data. Real-world: LinkedIn (LIquid), Uber Eats (graph learning for food discovery), Walmart (Neo4J product recommendations), NASA (Neo4J for "lessons learned" data).

10

Key-value databases: O(1) fetch, nothing fancy

Key-value databases store a value against a unique key and fetch it in constant O(1) time with no query language β€” just a lookup. The value ranges from a simple string to a complex object graph. That minimum latency makes their primary use case caching, and they're also used to hold consistent state across a distributed system. Popular: Redis, Hazelcast, Riak, Voldemort, Memcached.

Pick a key-value store when you need super-fast fetches with minimum fuss. Typical uses: caching, user state and sessions, real-time data, queues, leaderboards in games, pub-sub systems. Real-world: Twitter (Redis in its infrastructure), Google Cloud (Memcached for caching).

11

Time-series databases: data over time

Time-series databases are optimized for data that's continually read and written over time β€” data points tied to events, tracked and aggregated by business logic. The data streams from IoT devices, self-driving vehicles, industry sensors, social networks, and stock-market feeds. Studying it reveals system behavior, user patterns, and anomalies over time, feeding analytics that drive business decisions. Regular databases aren't built for this; with IoT's rise, time-series stores are increasingly adopted. Popular: InfluxDB, TimescaleDB, Prometheus.

Pick a time-series DB when you manage real-time data continuously over a long period: IoT ingestion, monitoring and analytics, or an autonomous trading platform tracking changing stock prices. Real-world: Uber (M3DB for metrics workflows), Airbnb (Apache Druid for real-time analytics).

12

Wide-column & Bigtable: storing big data by column

Wide-column, column-oriented, and column-family databases are NoSQL stores built for BigData β€” highly available, scalable, and distributed, mostly avoiding joins to scale read/write performance linearly. Popular: Google Bigtable, Apache Cassandra, HBase. To understand them, start with how data sits on disk.

Row vs. column storage

Row-oriented (OLTP) C1 | Alice | NYC | USA C2 | Bob | London | UK C3 | Cara | Delhi | IN one customer = one contiguous block fast row fetch & write Column-oriented (OLAP) id C1 C2 C3 name Alice Bob Cara country USA UK IN one column = one contiguous block scan just "country" for analytics
Figure 6 β€” Row storage keeps a record together (great for OLTP writes); column storage keeps a field together (great for OLAP scans + compression). Original diagram after Illustrations 1.65–1.66.

Row-oriented (MySQL, PostgreSQL) stores each record's fields together in contiguous disk blocks β€” ideal for OLTP: fetch or update a whole customer easily. Column-oriented (Google BigQuery, Amazon Redshift) stores each column together β€” ideal for OLAP: to find "% of customers from a country," it scans only the country column instead of traversing billions of full rows, and similar column data compresses well (e.g. run-length encoding). The flip side: inserting a new record touches every column, so writes are costlier. Column-family databases group similar columns into families, with a row spanning multiple families.

Google Bigtable: a column-family store

Bigtable is a distributed column-oriented database scaling to petabytes across thousands of commodity servers, powering 60+ Google products (Earth, Finance, web-search indexing, Analytics). Formally it's "a sparse, distributed, persistent multidimensional sorted map" β€” sparse meaning most cells are empty. Its key is a (row key, column key, timestamp) tuple and the value is a byte array.

Two cluster architectures

HBase Β· master-slave master / name node region svr region svr ZooKeeper client asks ZooKeeper for region Cassandra Β· peer-to-peer node node node node node all nodes identical, no SPOF
Figure 7 β€” HBase's master-slave (name node + region servers, coordinated by ZooKeeper) vs. Cassandra's peer-to-peer ring (identical nodes, no single point of failure). Original diagram after Illustrations 1.69–1.70.

HBase (modeled on Bigtable) uses master-slave: data starts in one region, splits into regions managed by region servers as it grows, the master watches them, and clients ask ZooKeeper which region server holds the data. Cassandra (write-intensive) uses peer-to-peer: every node is identical and runs the same code β€” giving architectural simplicity, no single point of failure, and add/remove nodes on the fly. Pick a wide-column DB when you're grappling with Big Data and need scalability, performance, and high availability. Real-world: Adobe and others use HBase for large-scale data processing.

13

Recap & the database picker

Database Pick it when… Examples
Relational You need relationships, transactions, or strong consistency (money, banking). MySQL, PostgreSQL
Document Semi-structured data, flexible/evolving schema, fast scaling, CRUD. MongoDB, CouchDB
Graph Complex relationships: social, recommendations, fraud, routing. Neo4J
Key-value Super-fast O(1) fetch: caching, sessions, leaderboards, queues. Redis, Memcached
Time-series Continuous real-time data over time: IoT, monitoring, trading. InfluxDB, Prometheus
Wide-column Big Data at scale with high availability and analytics. Bigtable, Cassandra, HBase
Shape first Structured, unstructured, semi-structured, or user state β€” the data's shape narrows the field.
Relational vs. NoSQL ACID + relationships vs. on-the-fly scaling + flexibility. Neither is "faster" β€” design decides.
Consistency is a dial Eventual (available, may lag) vs. strong (locked, always correct). CAP forces the choice under partition.
Mix freely Polyglot persistence uses many stores; multi-model databases fold several models into one API.
πŸ’‘
The single idea underneath it all

Every database is a bet about what you're willing to give up. Relational buys you consistency and relationships by giving up effortless scale; NoSQL buys scale by giving up global ACID; each specialized store wins one job by being useless at the others. There's no silver bullet because you're not hunting werewolves β€” you're matching a trade-off to a use case.

14

Further reading

The lessons cite many external links. Below are the ones that resolve live today, grouped by topic. Several cited links returned errors and are omitted (noted in the footer).

Relational at scale

[1]
The infrastructure behind Twitter scale β€” Twitter Engineering Why read it: how Twitter runs its infrastructure at scale, including its use of Redis (Section 10). ⚠ Dated 2017

Document databases in production

[2]
SEGA HARDlight migrates to MongoDB Atlas β€” MongoDB Why read it: a real document-store deployment improving experience for millions of mobile gamers (Section 08).
[3]
How we're able to host 1 million sites per MongoDB cluster β€” Wix Engineering Why read it: MongoDB at extreme scale β€” the operational side of a document store (Section 08).

Graph databases in production

[4]
Walmart's competitive advantage with Neo4j Why read it: real-time product recommendations powered by a graph database (Section 09).
[5]
How NASA uses Neo4j for "lessons learned" β€” Neo4j Why read it: a knowledge-graph use case storing mission lessons to educate engineers (Section 09).

Wide-column at scale

[6]
Powered by Apache HBase Why read it: the roster of institutions running HBase for large-scale data β€” the wide-column architecture of Section 12.