New: Try Voli The Bear, Fast package manager (and not only) for Windows
Updated Jul 10, 2026 Edit on GitHub

Outgrowing the Sheet: SQL & Databases

You hit one of the walls from Phase 1 - the file got slow, the IDs got mangled, or three "final" versions disagreed. That's not a failure. It's the signal that your data has grown up and needs a home built for the job. That home is a database, and the language you use to talk to it is SQL.

Here's the reassuring part: a database isn't a strange new world, it's a spreadsheet's ideas made sturdy. If you understand a sheet, you're most of the way to understanding a table.

The mental model: a table is a sheet that keeps its promises

📝 Terminology. A database is an organized store of data, managed by software built to keep it correct and fast. A table is one collection of data inside it - rows and columns, like a single spreadsheet tab. SQL (Structured Query Language) is how you ask the database to fetch, filter, or change data.

The shapes map almost one-to-one:

   SPREADSHEET                          DATABASE
   ───────────                          ────────
   a sheet/tab          →               a table
   a row                →               a row  (one record: one order, one user)
   a column             →               a column  (but with a DECLARED type)
   a cell               →               a value
   a formula / VLOOKUP  →               a SQL query (asked of the whole table)

What just happened: The pieces are the same. The difference is everything around them. A table declares what each column holds and refuses anything that doesn't fit, the database is one shared store instead of a file you copy, and SQL lets you ask questions across millions of rows without dragging a formula anywhere. Each of those maps to a Phase 1 pain.

One shared source of truth

In Phase 1, files multiplied until nobody knew which number was real. A database fixes this at the root: there is one table, living in one place, and everyone connects to that same table. There's no copy in someone's Downloads folder, because there are no copies - only connections.

   Spreadsheet world:                  Database world:

   you ── budget_v2.xlsx                you ─┐
   me  ── budget_FINAL.xlsx            me  ─┼─→  ONE orders table
   her ── budget_USE_THIS.xlsx         her ─┘    (everyone sees the same rows)

What just happened: The "which version is current?" question disappears, because there's only ever one version. Read the orders table and you're reading the live, current data - the same data your teammate sees at the same moment. Next time two reports disagree, there's no afternoon spent hunting for the "right" file - there's one table, and the answer is whatever it says right now.

Real types and constraints

In Phase 1, a "date" column was a mix of real dates and look-alike text, and IDs got auto-mangled. A database makes you declare each column's type up front - and then it enforces that promise on every single row, forever.

   CREATE TABLE orders (
     id          INTEGER,          ← whole numbers only
     customer    TEXT,             ← any text
     amount      DECIMAL,          ← money, kept exact
     ordered_at  DATE              ← real dates only; "March 1" with no year is rejected
   );

What just happened: You told the database the rules once. Now if anything tries to put the word "soon" into ordered_at, the database refuses it instead of silently storing text that looks like a date. The guard rail the spreadsheet never had is now built into the column itself.

📝 Terminology. A constraint is a rule the database enforces on a column - for example, "this value can't be empty," or "every id must be unique." It's the database catching bad data at the door, rather than you finding it three weeks later in a broken report. The whole class of bug where one stray text cell silently breaks a SUM, or a part number loses its leading zeros, is simply gone - the wrong shape isn't allowed in.

Querying millions of rows

In Phase 1, the sheet slowed to a crawl and then hit a hard row ceiling. Databases are built for the opposite: engineered to filter, sort, and summarize enormous tables quickly, because that's their entire job. You don't drag a formula down a million rows - you write one sentence describing what you want, and the database figures out how to get it fast. A SELECT query is you saying "give me these columns, from this table, where these conditions hold."

SELECT customer, amount
FROM orders
WHERE amount > 100;
   customer   amount
   ────────   ──────
   Ada        250.00
   Grace      140.00
   Lin        199.50

What just happened: You asked one question - "show me the customer and amount for every order over 100" - and the database scanned the whole orders table and handed back only the matching rows. It does the same whether the table has a hundred rows or a hundred million, and it doesn't melt your laptop doing it. "The file is too big to open" stops being a sentence you say - bigger data is just a longer scan, not a wall.

The grammar of SELECT … FROM … WHERE … is the single most useful thing to learn here, and it has its own guide: Querying Basics: SELECT & WHERE. If this is your first SQL query, read that next.

Multiple users, safely

A shared spreadsheet lets several people edit at once, but resolves clashes crudely - often the last save wins, quietly erasing someone else's change. Databases are designed from the start for many people and programs reading and writing at once without trampling each other.

📝 Terminology. A transaction is a group of changes the database treats as all-or-nothing: either every step succeeds, or none of them do. It's how a database moves money from one account to another without ever leaving it half-moved - even if two people press "go" at the same instant.

What just happened: Where the spreadsheet's answer to "two people, same data" was "hope for the best," the database's answer is a set of rules that keep the data correct no matter how many people are touching it - the difference between a tool for one person and a tool for a team. As soon as more than one person, or one automated script, depends on your data, you need it to stay correct under simultaneous use. The database gives you that for free; the spreadsheet never could.

A worked move: the same task, leveled up

Picture the Phase 1 ritual: every Monday, opening a sheet of this week's orders and, by hand, filtering to the big ones and eyeballing the total. In a database, that becomes a question you ask:

SELECT customer, SUM(amount) AS total
FROM orders
WHERE ordered_at >= '2026-06-15'
GROUP BY customer;
   customer   total
   ────────   ──────
   Ada        490.00
   Grace      140.00

What just happened: One query did the filtering and the per-customer totaling in a single step - no dragging, no manual cleanup, reading the same live table everyone else does. Same result you used to assemble by hand, now one repeatable sentence.

Try it yourself. Same idea on a tiny library dataset - join two tables and count, the kind of question that would mean a fragile VLOOKUP in a sheet. Run it and tweak the WHERE:

SELECT a.name AS author, a.country, COUNT(b.id) AS books
FROM authors a
JOIN books b ON b.author_id = a.id
GROUP BY a.id
ORDER BY books DESC;

And that word - repeatable - is the bridge to Phase 3. You've fixed size, types, and the source of truth, but you're still the one running this query every Monday. What happens when even that should run on its own?

Recap

  1. A table is a spreadsheet's ideas made sturdy: rows and columns, but with declared, enforced types.
  2. A database gives you one shared source of truth - connections, not copies - so versions stop multiplying.
  3. Types and constraints catch bad data at the door, killing the "stray text broke my SUM" class of bug.
  4. Databases query millions of rows fast, and SQL (SELECT … FROM … WHERE …) is how you ask.
  5. They handle many users safely, with transactions keeping data correct under simultaneous use.

You can now hold a clean, shared, queryable source of truth. Next: what to do when the querying itself has to happen without you.


← Phase 1: Where Everyone Starts · Guide overview · Phase 3: When It Has to Run Itself →

Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.

Check your understanding 3 questions

1. How does the guide describe a database table relative to a spreadsheet?

2. What does declaring a column's type buy you?

3. What problem does moving from spreadsheet files to a database solve about versions?