Lesson 08 · Data Design

The Unreasonable Importance of the Schema

The first decision. The most permanent one.

Every decision the schema makes,
the code inherits.

The schema is the first thing you build and the last thing you want to change. Every table is a claim about how the world works, every column is a value you've decided matters, every foreign key is a rule encoded in stone. Most projects fail slowly because someone picked the wrong column name in week two.

1
Gate 01 · Structure

Everything is built on top of it

The house was built. Then someone moved a wall.

A schema defines tables, columns, types, and relationships. It is not documentation — it is enforcement. The database refuses to store what the schema forbids. Every query, API response, report, and dashboard is an expression of what you declared here. Change the schema and you change everything below it.

the stack

This is not a bad thing. Precision is the gift. But it comes with a cost: decisions made at the schema level ripple through the entire system. A column you add today will exist in production code, backup exports, analytics views, and documentation for years. The schema deserves care.


2
Gate 02 · Naming

Names live forever

They called it user_name. It's in a thousand places now.

Column names are permanent the moment you ship. They appear in SQL queries, JSON API responses, analytics dashboards, mobile app models, log files, test fixtures, and client SDKs. A name you choose on a Tuesday morning will still be there in five years, in six systems, referenced in code you haven't written yet.

one name, many places

The rules: be explicit (created_at not created), be consistent (never mix camelCase and snake_case in the same schema), and be specific (amount_cents not price, not cost, not value). Claude will generate code that matches your names exactly — give it names worth generating.


3
Gate 03 · Types

Types are contracts

The price was a string. The calculation was wrong for six months.

A type is not a storage format — it's a constraint on what this value is allowed to be. VARCHAR(255) for a monetary amount means "$12.99" is as valid as "twelve dollars" is as valid as an empty string. DECIMAL(10,2) means it's a number, it has two decimal places, and the database will enforce this. Every type you pick is a constraint you're accepting on behalf of every future query.

type as constraint

Common traps: booleans stored as strings ("true"/"false"), prices as floats (floating-point errors in money), IDs as sequential integers instead of UUIDs, timestamps without timezone. Each one feels harmless. Each one compounds. Ask Claude to review your types before you finalize the schema — it will catch the obvious ones before they're permanent.


4
Gate 04 · Integrity

FK constraints are the business logic

The order had no customer. The report was wrong for years.

A foreign key constraint is the machine-readable version of a business rule. "Every order must belong to a customer" is not a validation you write in application code — it's a declaration in the schema. Application code can be bypassed: scripts, migrations, direct database access, future engineers who didn't read the codebase. The schema constraint cannot.

referential integrity

Without a foreign key: a deleted user leaves orphaned orders. A bug in a migration creates records with no parent. An analytics query silently under-counts because half the rows have null user_id. These bugs are invisible until they're expensive. The fix — declare the constraint at schema design time — takes one line.


5
Gate 05 · Cost

The price of being wrong

Adding a column took an afternoon. Renaming one took a sprint.

Every wrong decision made at schema design time costs you a migration. Migrations on large tables are not free: locking, downtime risk, multi-step deploys, coordinated rollouts. The asymmetry is brutal — adding a nullable column to a 10-million-row table is fast. Renaming a column used in 200 queries, 15 API response shapes, and 3 analytics reports is a project.

cost of change over time

This is why senior engineers spend three times as long on schema review as on schema creation. The cost of a wrong decision is asymmetric — near-zero at design time, growing with every row added and every system built on top. Claude can help you get the design right — but only if you show it the schema before you build the application.


6
Gate 06 · With Claude

Give Claude the schema first

Claude read the code for an hour. The schema was one page.

When Claude works on a database-backed system, the schema is the most information-dense document in the project. Fifty lines of DDL conveys more about the domain model than five thousand lines of application code. Before asking Claude to write queries, build features, or diagnose data issues — give it the schema.

Here is my domain: [describe what your app does and what data it needs to track]. Design a normalized SQL schema. Use snake_case, add FK constraints, and explain any non-obvious type choices.

More importantly: design the schema with Claude before you write any application code. Show it your domain description and your data requirements. Ask it to identify naming inconsistencies, suspicious types, and missing constraints. The schema review you skip at design time will not be optional at scale.

Here is the schema: [paste CREATE TABLE statements]. Review it: naming consistency, type appropriateness, missing constraints, and anything that will be painful to change after launch.