← The Forge
Fundamentals Lab · Data 1

SQL — Theory & Practicum

One running example, start to finish: a person, and their phone number(s). Three design choices, then the same choices built and queried for real against Postgres — the database every real system in this seminar actually runs on.
Theory 1 of 3

One person, their phone number(s).

Every table design decision is really one question wearing a disguise: how many of this thing can one person have? The obvious first answer — a phone column right on the person's row — works perfectly for exactly one number. It breaks the moment someone has two. phone2, phone3... is the smell that tells you the design is wrong, not a normal way to grow a table.
Theory 2 of 3

The normalized answer: give it its own table.

Pull the repeating data out of the parent row entirely, into a phone_numbers table with a foreign key pointing back to the person. One row per number, no cap, no schema change to add a fourth. This is what "normalization" actually means. It costs you a JOIN every time you want a person's numbers back — which is exactly what the practicum below builds and runs.
Theory 3 of 3

Or: skip the join, pay for it later.

A third option — a JSON column holding an array right on the person's row — looks like the same fix with less schema. What it actually trades away: the database's ability to enforce structure, index a single number efficiently, or join against it like a real row. It wins when the shape is genuinely unpredictable or you'll never query inside it. A child table wins the moment you need to query, index, or join on the repeating thing — which is almost always, for phone numbers. Why Postgres specifically: it's the rare engine that does both well — real foreign keys and joins, and a genuinely good JSON type (jsonb) — so you're not force-committing to one model on day one.
Before the Practicum

Meet psql.

  • psql is Postgres's own command-line client — a terminal window, but instead of bash it understands SQL directly. You'll know you're in it because the prompt looks like aisem_demo=# instead of a bash prompt.
  • Click inside the black box below to focus it. Every SQL statement ends in a semicolon ; — that's what tells psql "run it now."
  • The two tables from the theory slides were built in a real Postgres database, and every query below was run against it for real — the results you'll see are the genuine output, replayed here exactly. Type the same queries into any real psql and you'll get the same answers.
Done

Every schema is that same question, asked over and over.

"How many of this thing can one person have?" — answer it wrong and you get a phone2 column, or a JOIN you didn't build. This is the exact call an agent makes silently every time it designs you a schema — including the ones the capstone lessons at the end of this track will have it design for you. Now you know enough to check its work instead of just trusting the table it hands you.
1 / 1
ends with a "mark complete" step