Module F-6·20 min read

PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK — letting the database enforce your rules so application code does not have to.

F-6 — Constraints and Data Integrity

Who this module is for: You completed F-5 and can query data across multiple tables. Now you need to understand how to make the database enforce your rules automatically — so bad data cannot enter even if your application has a bug. Constraints are the database's immune system.


Why Constraints Matter

Imagine a bug in your application that accidentally submits an order with customer_id = 999 — but no customer with ID 999 exists. Without constraints, PostgreSQL happily stores this invalid order. Your data becomes inconsistent: you have orders that reference customers who do not exist.

Or your application has a bug that allows two users to register with the same email address. Now you have duplicate accounts and authentication breaks.

Constraints prevent these problems at the database level — not in your application code, not in your API layer, but at the very last line of defence before data is written to disk.


PRIMARY KEY — Every Row Needs a Unique Identity

A primary key uniquely identifies each row. No two rows can have the same primary key value, and it can never be NULL.

sql

When you insert a row that violates the primary key:

sql

BIGSERIAL vs manual ID: when you use BIGSERIAL, PostgreSQL automatically assigns the next available integer. You never specify id in your INSERT — it is generated for you. This is the correct pattern for most tables.


NOT NULL — Mandatory Fields

NOT NULL prevents a column from ever being left empty.

sql

Rule: if a column must always have a value, add NOT NULL. If the value is sometimes unknown or optional, leave the column nullable. Be intentional — a column without NOT NULL silently accepts missing data.


UNIQUE — No Duplicates Allowed

UNIQUE ensures no two rows have the same value in that column (or combination of columns).

sql

When a unique constraint is violated:

sql

UNIQUE vs PRIMARY KEY:

  • PRIMARY KEY = unique + not null + the table's main identifier (one per table)
  • UNIQUE = no duplicates, but NULLs are allowed (and multiple NULLs count as different values in PostgreSQL)

FOREIGN KEY — Referential Integrity

A foreign key ensures that a value in one table references a real row in another table. It is the constraint that makes joins meaningful.

sql

What happens when you delete a referenced row?

By default, trying to delete a customer who has orders fails:

sql

You control this behaviour with ON DELETE:

sql

Which to use:

  • ON DELETE CASCADE — when child rows have no meaning without the parent (order items without an order)
  • ON DELETE SET NULL — when the relationship is optional and child rows are still useful alone (posts by a deleted user still exist, author is just unknown)
  • ON DELETE RESTRICT (default) — when you want explicit control and prefer to handle deletion in your application

CHECK — Custom Business Rules

CHECK enforces any condition you can express as a boolean SQL expression:

sql

DEFAULT — Automatic Values

DEFAULT specifies the value to use when a column is omitted from an INSERT:

sql

Adding Constraints to Existing Tables

You will often need to add constraints after a table already exists — because you are adding a rule to a live system:

sql

Viewing constraint names

PostgreSQL auto-generates constraint names if you don't provide one. Find them with:

sql

Practical Exercise: A Constrained Blog Schema

Build this schema from scratch, applying appropriate constraints at each step:

sql

Test your constraints:

sql

Summary

ConstraintWhat it enforces
PRIMARY KEYUnique + non-null identifier for each row
NOT NULLColumn must always have a value
UNIQUENo two rows can have the same value (NULLs are distinct)
FOREIGN KEYValue must reference an existing row in another table
ON DELETE CASCADEDelete child rows when parent is deleted
ON DELETE SET NULLSet FK to NULL when parent is deleted
ON DELETE RESTRICTBlock deletion if child rows exist (default)
CHECKAny boolean expression must be true
DEFAULTValue to use when column is omitted from INSERT

The philosophy: the database is the last line of defence. Enforce every rule you can at the database level — it is faster, safer, and catches bugs that application-level validation misses.


Module F-7 completes Phase 1 — building your first real application schema, connecting from application code, and the basic tools every engineer needs before moving to Phase 2.

Next: F-7 — Your First Real Application Schema →


Knowledge Check

A software team is designing a database schema for a social media platform. They have users and posts tables, where posts.author_id is a foreign key referencing users.id. The product requirement states that when a user account is deleted, their posts should not be automatically removed, but instead, the posts should be explicitly reviewed by a moderator for potential re-assignment to an 'anonymous' user or archival. Which ON DELETE strategy for the posts.author_id foreign key best supports this architectural requirement?


Consider a users table with a PRIMARY KEY on id and a UNIQUE constraint on the email column. During a data migration, an application bug causes several new user records to be inserted with NULL values for their email address, as the email was not yet available. Assuming no NOT NULL constraint is explicitly defined on the email column, what is the expected behavior regarding the UNIQUE constraint on email for these NULL entries in PostgreSQL?


A critical products table in a high-traffic e-commerce system, containing millions of rows, was initially designed without a NOT NULL constraint on its price column. Due to recent data integrity issues, the engineering team decides to add this constraint to ensure all new and existing products have a defined price. The command ALTER TABLE products ALTER COLUMN price SET NOT NULL; is executed during peak hours. What is the most significant production impact or operational consideration during this operation?

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 & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.