Module 6: Databases & Auth with Supabase
Lesson 1

What Is a Database? Tables, rows & SQL in plain English


Up to now, your app has been keeping its data in memory — inside the browser tab. Useful for a demo, useless for a real product. The moment the tab closes, everything is gone.

A database fixes that. This lesson explains what a database actually is, in language that assumes you've never written a line of SQL. You won't need to memorize anything — Claude writes the code for you. You just need a mental model so you can describe what you want and recognize what you're looking at.


The Problem Without a Database

When data only lives in the browser, your app can't do any of the things that make software feel real:

  • No user accounts
  • Data disappears on every page refresh
  • No way to support more than one person
  • No record of anything that happened

A database is organized storage for information that survives. Once your app talks to one, data sticks around — across refreshes, across sessions, across users.


What a Database Actually Is

The most common kind of database — and the one Supabase uses — is a relational database. The easiest way to picture it: a collection of spreadsheets that can be linked to each other.

Each spreadsheet is a table. Each row is a record. Each column is a field.

Here's a tasks table:

idtitledonecreated_atuser_id
1Buy groceriesfalse2024-01-15abc123
2Finish proposaltrue2024-01-15abc123
3Call dentistfalse2024-01-16xyz789

That's it. A database table is just structured storage. Not magic, not intimidating — a spreadsheet with rules.


Key Concepts (The Whole Vocabulary)

Tables

The main storage units. Each kind of "thing" your app remembers gets its own table.

  • A task app might have: tasks, users
  • A client portal might have: users, projects, updates
  • A blog might have: users, posts, comments

Rows (Records)

One row is one item. One task. One user. One post.

Columns (Fields)

Each column defines a property that every row in the table has. Almost every table needs two columns:

  • id — a unique identifier for each row (auto-generated)
  • created_at — when the record was created (Supabase adds this for you)

After that come your app-specific columns: title, content, done, status, and so on.

Primary Key

The id column. Because every row has a unique id, you can point to exactly one record with no ambiguity — "update the task with id 2," not "update the task that's roughly in the middle."

Foreign Key

A way to link two tables together. If a task belongs to a user, the tasks table holds a user_id column containing that user's id. That single link is how your app knows which tasks belong to which person.


SQL: The Language of Databases

Databases are queried with SQL (Structured Query Language). A query looks like this:

SELECT * FROM tasks WHERE user_id = 'abc123' ORDER BY created_at DESC;

In plain English: "Give me all tasks belonging to user abc123, newest first."

You do not need to become fluent in SQL for this course. But it's worth being able to recognize it, because:

  • Supabase's dashboard lets you run SQL directly
  • Claude Code writes SQL for you when it's needed
  • Error messages sometimes contain SQL when something breaks

The four verbs worth knowing:

SQL keywordWhat it does
SELECTRetrieve data
INSERT INTOAdd new data
UPDATEChange existing data
DELETE FROMRemove data

These four are so fundamental they have a nickname: CRUD — Create, Read, Update, Delete. Most of what an app does with data is some combination of these four. A later lesson is entirely about wiring them up.


Why Supabase?

You have plenty of database options. Here's why Supabase fits this course so well:

FeatureSupabaseFirebasePlanetScaleRaw PostgreSQL
Free tierGenerousLimitedGoodSelf-hosted only
Dashboard GUIExcellentGoodGoodVaries
Built-in authYesYesNoNo
SQL-basedYesNoYesYes
Next.js integrationExcellentGoodGoodManual
Learning curveLowLowMediumHigh

Under the hood, Supabase is PostgreSQL — one of the most battle-tested database systems in the world. What Supabase adds is a friendly dashboard, built-in authentication, and an API that's far gentler than raw SQL.


How Supabase Fits Into Your App

The flow looks like this:

Browser / App
    ↓
Supabase Client (code you'll add)
    ↓
Supabase API
    ↓
PostgreSQL Database (Supabase manages this for you)

From your app's code, instead of writing raw SQL, you call the Supabase client:

const { data, error } = await supabase
  .from('tasks')
  .select('*')
  .eq('user_id', currentUser.id)

That reads almost like English: "from tasks, select everything where user_id equals the current user's id." Claude writes this for you — you just need to roughly understand what it's doing.


A Quick Security Word (Read This Twice)

Supabase gives your project two keys. You'll use them in later lessons, but the rule starts now:

  • The anon / publishable key is safe to use in browser code. It's designed to be public.
  • The service_role key is a master key that bypasses all security rules. It must never appear in browser code, in any NEXT_PUBLIC_* variable, or anywhere a visitor could see it. It is server-only, always.

You'll also turn on Row Level Security (RLS) on every table — the system that ensures one user can't read or delete another user's data. We cover both in detail soon; for now, just know these are non-negotiable.


Plan Your Data Before You Build

Before setting anything up, sketch what your app needs to remember. Ask: "What things does my app need to keep track of?"

Task app:

  • Tasks (title, done status, owner)
  • Users (handled by Supabase Auth automatically)

Client portal:

  • Clients (name, email — handled by Supabase Auth)
  • Projects (name, status, which client)
  • Updates (text, date, which project)

Blog:

  • Users (authors — Supabase Auth)
  • Posts (title, content, author, published status)

Write your tables out before the setup lesson. You can refine them later, but a starting sketch makes everything faster.

Help me design the database tables for my app. It's a [describe your app]. List the tables I'll need, the columns in each, and how they link together. Keep it simple — this is my first database.


Summary

  • A database is organized storage for data that persists beyond a browser session.
  • Relational databases are like linked spreadsheets: tables (rows = records, columns = fields).
  • Every table needs an id (primary key) and usually a created_at; foreign keys link tables together.
  • SQL is the language of databases; the four core operations are CRUD — Create, Read, Update, Delete. Claude writes the SQL for you.
  • Supabase wraps PostgreSQL in a friendly dashboard and API, with auth built in.
  • Security rule from day one: the anon key is public-safe, the service_role key is server-only and never goes in the browser.