CMD Guide
HomeSystem DesignDatabases

Introduction to Databases

A database is a program that lays records out on disk in a structure it can find again by key or index — so a lookup touches a few blocks instead of scanning everything — and the SQL-versus-NoSQL split is fundamentally a choice about where that structure is enforced: the relational engine validates every row against a declared schema when you write (schema-on-write), while most NoSQL stores accept whatever shape you send and leave your application code to make sense of it when you read (schema-on-read). Everything else — query language, scaling story, ACID guarantees — follows from that one decision.

The two families

A Database Management System (DBMS) is the software layer between your application and the bytes on disk; it handles concurrent access, durability, and querying so you never touch raw files. Two families dominate:

"NoSQL" is not one thing. A Redis key-value cache and a Neo4j graph engine have almost nothing in common except that neither is a relational table — so blanket statements like "NoSQL scales better" or "NoSQL has no schema" are usually wrong for at least one member of the family.

The five dimensions, corrected

These are the axes engineers actually compare on. Two claims you will see repeated in older material are wrong today and are fixed below.

DimensionSQL (relational)NoSQL (varies by model)
1. StorageRows in typed tables; one row = one entity, one column = one attribute (a car has columns make, model, year).Documents, key→value pairs, column families, or nodes+edges — chosen to match how you read the data.
2. SchemaDeclared up front and enforced by the engine on every write. It can be changed later — and on modern engines many changes are online (see below), not a rebuild-and-go-offline event.Flexible: fields vary per record; you add a field just by writing it. The schema still exists — it has just moved into your application code and into the mix of record versions on disk.
3. QueryingSQL — a declarative, standardized language the optimizer turns into an execution plan.Per-product APIs and query languages (MongoDB's query documents + aggregation pipeline, Cassandra's CQL, Cypher for graphs). There is no shared "NoSQL query language."
4. ScalingTraditionally scaled up (bigger box). Sharding across nodes is possible but you own the complexity. Managed products (Aurora, Spanner, Vitess) now scale out too.Designed to scale out across commodity nodes; many auto-distribute data by a partition key. The cost is paid in the partition-key design.
5. Transactions / ACIDFull ACID is the default and the reason to reach for relational when correctness of multi-row changes matters (money, inventory).Historically relaxed to BASE for availability and speed — but this is dated as a blanket claim: MongoDB has multi-document ACID transactions, DynamoDB has transactions, Spanner is globally-distributed ACID.

Correction 1 (Schema): "Altering the schema means modifying the whole database and going offline" is false on current engines. PostgreSQL and MySQL 8+ support online DDL: adding a nullable column, or a column with a default, is a metadata-only change that completes in milliseconds without rebuilding the table. One precision the folklore version drops: the ALTER still needs a brief exclusive lock (ACCESS EXCLUSIVE in PostgreSQL; a short metadata lock in MySQL's INSTANT DDL) — so if a long-running transaction already holds the table, the ALTER queues behind it and every query issued after the ALTER queues behind the ALTER. That queue-behind-a-long-transaction pile-up is the classic online-DDL production incident. Mitigation: run DDL with a lock_timeout and retry, or schedule it off-peak.

Correction 2 (Querying): older summaries call the NoSQL query language UnQL (Unstructured Query Language). UnQL was a short-lived 2011 proposal that never shipped in any mainstream database — it is not a standard and you will never meet it in production. Each NoSQL product has its own API.

Worked example: one car catalog, two engines

Take three products and trace what actually happens on disk and on the wire.

Relational (PostgreSQL) — schema on write

CREATE TABLE cars (
  id     BIGINT PRIMARY KEY,
  make   TEXT NOT NULL,
  model  TEXT NOT NULL,
  year   INT  NOT NULL
);

INSERT INTO cars VALUES (1, 'Toyota', 'Corolla', 2020);
INSERT INTO cars VALUES (2, 'Honda',  'Civic',   2019);

-- Marketing now wants a colour. Naive fear: "this rebuilds the table + downtime."
-- Reality on PG / MySQL 8:
ALTER TABLE cars ADD COLUMN color TEXT;   -- metadata-only, ~1 ms, no table rewrite; still takes a BRIEF exclusive lock

INSERT INTO cars VALUES (3, 'Tesla', 'Model 3', 2023, 'Red');
SELECT make, model FROM cars WHERE year >= 2020;  -- engine uses the year to filter; returns rows 1 and 3

Trace of the write path for row 3:

  1. Parser + planner validate the statement against the catalog: 5 values, 5 columns, types match. If year were 'twenty-twenty-three' the write is rejected here — the bad data never lands.
  2. Row is written to the WAL (durability) then to a data page.
  3. Because color was added as a nullable column, rows 1 and 2 were never touched — the engine reads their missing color as NULL. That is why the ALTER was instant.

Document (MongoDB) — schema on read

db.cars.insertOne({ _id: 1, make: "Toyota", model: "Corolla", year: 2020 })
db.cars.insertOne({ _id: 2, make: "Honda",  model: "Civic",   year: 2019 })

// Adding colour needs no migration — you just include the field:
db.cars.insertOne({ _id: 3, make: "Tesla", model: "Model 3", year: 2023, color: "Red" })

db.cars.find({ year: { $gte: 2020 } }, { make: 1, model: 1 })

Trace of the read path: the collection now holds documents of two different shapes — rows 1 and 2 have no color key at all. Nothing rejected the mismatch on write; instead your application (or a $exists check) must handle "the field may be absent" at every read. The flexibility on write became a branch in your read code. That is the whole trade in one sentence.

diagram
diagram

When to use which — how a senior engineer decides

The decision is not "which is better" but "where does the cost of structure belong for this workload."

Choose relational (SQL) when:

Prefer a NoSQL model when:

Crisp rule: choose relational when your data has relationships and you need transactional correctness with flexible queries; prefer a specific NoSQL model when one access pattern dominates and you will trade query flexibility and cross-record integrity for scale, latency, or a natural fit to that pattern. Many mature systems run both — Postgres as the system of record, Redis as the cache, Elasticsearch for search.

Pitfalls

Takeaways

Interview drill ladder


Re-authored and deepened for this guide. Sources: Designing Data-Intensive Applications (Martin Kleppmann, ch. 2, on schema-on-write vs schema-on-read); PostgreSQL documentation on ALTER TABLE and MySQL 8.0 documentation on Online DDL (ALGORITHM=INSTANT); MongoDB documentation on multi-document ACID transactions; Amazon DynamoDB and Google Cloud Spanner transaction docs. The "UnQL" term traces to the abandoned 2011 UnQL specification and is corrected here as non-standard.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction to Databases? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction to Databases** (System Design) and want to truly understand it. Explain Introduction to Databases from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction to Databases** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction to Databases** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction to Databases** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes