Translating a real-world problem into tables, connecting from application code, and basic backup and restore.
F-7 — Your First Real Application Schema
Who this module is for: You have completed all of Phase 1. You can create tables, query, filter, aggregate, join, and enforce constraints. Now you need to put it all together: design a schema for a real application, connect to it from application code, and understand the tools that keep schemas manageable as they evolve. This module closes the Foundation phase and prepares you for the Practitioner topics ahead.
From Concepts to Real Design
A schema for a real application starts with questions, not SQL:
- What are the entities? The "things" your application manages — users, tasks, projects, comments
- What attributes does each entity have? The data that describes each thing
- What are the relationships? How entities relate — a task belongs to a project, a user can have many tasks
This process is called data modelling. You do not need formal methodology — just answer these three questions before writing any SQL.
Example: A Task Management Application
Entities:
- Users (who uses the app)
- Projects (containers for tasks)
- Tasks (the work items)
- Comments (discussion on tasks)
Attributes:
- User: username, email, password hash, created date
- Project: name, description, owner user, created date
- Task: title, description, status, assignee, project, due date, created date
- Comment: content, author, task, created date
Relationships:
- A user owns zero or more projects (one-to-many)
- A project has zero or more tasks (one-to-many)
- A task belongs to exactly one project (many-to-one)
- A task can be assigned to zero or one user (optional many-to-one)
- A task has zero or more comments (one-to-many)
- A user can be a member of multiple projects, and a project has multiple members (many-to-many)
The Complete Schema
Verifying the Schema
Seeding Test Data
Querying the Schema
Connecting From Application Code
PostgreSQL stores your data — but your application needs to connect to it. Here is the minimal setup for the two most common stacks.
Node.js with pg
Never build SQL by string concatenation with user input:
Python with psycopg2
Schema Migrations: Managing Change
Schemas change. You add columns, rename things, add constraints. In development, you can DROP DATABASE and start over. In production, you cannot — there is live data there.
Schema migrations are versioned SQL scripts that transform the schema from one state to another.
Manual Migrations (the concept)
Migration Tools
In practice, teams use migration tools that:
- Track which migrations have been applied
- Run new migrations automatically on deploy
- Allow rollback if something goes wrong
Popular options by stack:
| Stack | Tool |
|---|---|
| Node.js | Drizzle ORM, Prisma Migrate, node-pg-migrate, Flyway |
| Python | Alembic (SQLAlchemy), Flyway |
| Ruby | ActiveRecord Migrations |
| Java | Flyway, Liquibase |
| Any | Flyway (JVM-based, works with any stack) |
For a beginner Node.js project, node-pg-migrate is simple:
pg_dump — Your Safety Net
Before any schema change on a real database, take a backup:
Get in the habit of pg_dump before anything that modifies schema structure.
What Phase 1 Has Given You
By completing Modules F-1 through F-7, you can:
✅ Install PostgreSQL and use psql confidently
✅ Design a schema from a real-world problem
✅ Use correct data types for every situation
✅ Write every fundamental SQL operation
✅ Filter, sort, and aggregate data
✅ Join data across multiple tables
✅ Enforce data integrity with constraints
✅ Connect from application code safely (parameterised queries)
✅ Understand schema migrations conceptually
This is the foundation that every PostgreSQL engineer builds on. Phase 2 — The Practitioner takes you from isolated scripts to real production application patterns: advanced SQL, indexing, transactions, JSON, full-text search, access control, and deployment.
Summary
| Concept | Key Takeaway |
|---|---|
| Data modelling | Identify entities, attributes, and relationships before writing SQL |
| Junction tables | Model many-to-many relationships with a third table |
| Consistent timestamps | created_at, updated_at, soft-delete with archived_at / deleted_at |
| Parameterised queries | Always use $1, $2 placeholders — never string concatenation with user input |
| Schema migrations | Version your schema changes; never manually ALTER in production without a migration |
pg_dump | Backup before any structural change |
Phase 1 is complete. Phase 2 — The Practitioner — begins with Module P-1: Advanced SQL, covering CTEs, window functions, upserts, and the patterns every production engineer uses weekly.
Next: P-1 — Advanced SQL — The Patterns You Will Use Every Week →
A Senior Engineer is reviewing the taskmanager schema's foreign key ON DELETE actions. If a users record is attempted to be deleted, which of the following statements accurately describes the *immediate* production behavior based on the provided schema?
A junior developer implements a user search feature using string concatenation for SQL queries, similar to the ❌ SQL INJECTION VULNERABILITY example. During a security audit, it's identified that an attacker could input ' OR '1'='1 into the search field. What is the most critical implication of this vulnerability in a production environment?
A team needs to add a new priority_level column to the tasks table in a production environment. They are debating between manually running ALTER TABLE commands directly on the production database or using a schema migration tool like node-pg-migrate. As a Senior Principal Software Engineer, what is the primary reason to strongly advocate for using a migration tool?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
Sign in & RegisterDiscussion
0Join the discussion