RadarTrek
Home/Courses/Database Design for Builders
๐Ÿ—ƒ๏ธIntermediate8 lessons ยท 2 free

Database Design for Builders

Most developers learn SQL syntax but never learn how to design a database. This course fills that gap: how to model real-world data relationships, when to normalize vs denormalize, how indexes actually work and when to add them, how to write migrations safely, and how to use Row Level Security in Supabase to enforce access control at the database layer.

Prerequisites: Some programming experience
Start free lessons
$69one-time ยท lifetime access

What you'll learn

โœ“How to model real-world data โ€” entities, attributes, relationships, and drawing ERDs before writing SQL
โœ“Normalization in practice โ€” 1NF, 2NF, and 3NF explained plainly, and when to break the rules deliberately
โœ“Keys, constraints, and foreign key ON DELETE behaviour โ€” the discipline of NOT NULL and check constraints
โœ“Indexes that actually help โ€” B-tree mechanics, EXPLAIN ANALYZE, partial indexes, and covering indexes
โœ“Designing for SaaS โ€” multi-tenancy patterns, a complete SaaS schema, and ULID vs UUID
โœ“Row Level Security patterns โ€” database-enforced access control that application bugs cannot bypass
โœ“Migrations without drama โ€” forward-only migrations, safe column changes, and zero-downtime deploys
โœ“Schema for real products โ€” a complete worked Invoice Manager SaaS schema from scratch

Course outline

Full course โ€” $69 one-time

03

Keys, Constraints, and References

Primary keys, foreign keys, ON DELETE behaviour, and the discipline of NOT NULL

10 min
04

Indexes That Actually Help

How B-tree indexes work, when Postgres uses them, and when they slow you down

11 min
05

Designing for SaaS

Multi-tenancy patterns, a complete SaaS schema, and per-tenant configuration with JSONB

11 min
06

Row Level Security Patterns

Lock down your data at the database layer โ€” so application bugs cannot expose other tenants

11 min
07

Migrations Without Drama

Forward-only migrations, safe column changes, and zero-downtime deploys against live data

11 min
08

Schema for Real Products

A complete schema review โ€” what you built, what breaks at scale, and how to think beyond MVP

14 min

Get the full course

8 lessons โ€” from entity modelling to RLS policies, safe migrations, and a complete production SaaS schema.

โœ“ 8 lessonsโœ“ Production Postgres patternsโœ“ Certificate
$69one-time

Written by the RadarTrek editorial team ยท Reviewed June 2026

About this course

A well-designed database schema is the foundation of a maintainable application โ€” poor schema decisions compound into a tax on every feature you build. Learning database design means understanding normalisation, relationships, indexing, how to model common application patterns, and how to evolve a schema over time without breaking existing data. This database design tutorial for application developers uses PostgreSQL and covers the decisions you face when building real products, not abstract theory.

Database design skills are valuable for every backend and full-stack developer. After this course you will be able to design a relational schema that models your application domain correctly, choose between normalisation and denormalisation for your access patterns, write the indexes that make queries fast, handle schema migrations safely, and avoid the common mistakes that create performance and consistency problems at scale.

Frequently asked questions

What is database normalisation and do I need it?

Normalisation is the process of structuring a database to reduce data redundancy and improve integrity. The most important rules: store each piece of information once (do not repeat data across multiple rows), ensure every column in a table depends on the whole primary key, and use foreign keys to express relationships. In practice, follow normalisation principles by default and denormalise deliberately when query performance genuinely requires it.

When should I use a foreign key constraint?

Use foreign keys whenever two tables have a relationship โ€” when a row in one table references a row in another. A foreign key constraint enforces that the referenced row exists and prevents orphaned data. Example: orders.user_id should reference users.id. Without the constraint, deleting a user could leave orders pointing to a nonexistent user. Foreign keys with appropriate ON DELETE behaviour (CASCADE, SET NULL, RESTRICT) keep your data consistent.

What is an index and when should I add one?

An index is a data structure that lets the database find rows matching a condition without scanning the entire table. Add indexes on: foreign key columns (if not automatically indexed), columns used in WHERE clauses of frequent queries, columns used in ORDER BY for large result sets. Check query performance with EXPLAIN ANALYZE in PostgreSQL. The cost of over-indexing is slower writes and increased storage; the cost of under-indexing is slow queries on large tables.

How do I handle many-to-many relationships?

Many-to-many relationships require a junction table (also called a join table or association table) with foreign keys to both sides. Example: a user can have many tags, and a tag can apply to many users. Create a user_tags table with user_id and tag_id columns, each being a foreign key. The junction table can also store relationship attributes โ€” the date a tag was applied, who applied it.

How do I run database migrations safely in production?

Safe migrations: add nullable columns rather than NOT NULL columns without defaults (existing rows cannot satisfy NOT NULL without data), never rename columns directly (add the new name, backfill data, update code, then drop the old name), run large data migrations in batches to avoid table locks, and always test migrations against a copy of production data before running in production. Use a migration tool (Prisma Migrate, Flyway, or plain SQL migration files) to track which migrations have run.

RadarTrek Intel โ€” monthly score updates

We track 40+ tools so you don't have to. Score changes, new tools, and new guides โ€” once a month, no spam.