Constraints: UNIQUE, CHECK, FOREIGN KEY
Go beyond the basics — block duplicate values with UNIQUE, validate values with CHECK and link tables with FOREIGN KEY.
PRIMARY KEY, NOT NULL and DEFAULT handle the basics. Real databases need three more rules: "no two players can wear the same jersey number" (UNIQUE), "runs can never be negative" (CHECK) and "a player's team must be a team that actually exists" (FOREIGN KEY).
Definitions
UNIQUE ensures that no two rows have the same value in a column (or combination of columns). Unlike a primary key, a table can have many UNIQUE constraints, and the column may contain NULL.
CHECK ensures that every value in a column satisfies a condition (a true/false expression), such as
runs >= 0. A row whose value makes the condition FALSE is rejected.
FOREIGN KEY is a column in one table that refers to the primary key (or a unique key) of another table. It guarantees that every value you store already exists in the referenced table, keeping the two tables consistent (this is called referential integrity).
Summary table
| Constraint | Protects against | IPL example |
|---|---|---|
UNIQUE | Duplicate values | Two players with jersey no. 18 in one team |
CHECK | Invalid values | runs = -50, strike_rate = 5000 |
FOREIGN KEY | "Orphan" values that point nowhere | A player in team 'XYZ' which doesn't exist in teams |
Syntax
sql
CREATE TABLE table_name (
col1 data_type UNIQUE, -- column-level UNIQUE
col2 data_type CHECK (condition), -- column-level CHECK
col3 data_type,
CONSTRAINT uq_name UNIQUE (col1), -- table-level, named
CONSTRAINT ck_name CHECK (col2 >= 0),
CONSTRAINT fk_name FOREIGN KEY (col3)
REFERENCES parent_table (parent_column)
);PRIMARY KEY vs UNIQUE
| PRIMARY KEY | UNIQUE | |
|---|---|---|
| Duplicates allowed? | No | No |
| NULL allowed? | No | Yes (SQL Server allows only one NULL; MySQL/PostgreSQL allow many) |
| How many per table? | One | Many |
| Purpose | The row's identity | Business rule (email, jersey no., etc.) |
Example — CHECK and UNIQUE
sql
CREATE TABLE squad (
id INT NOT NULL,
name VARCHAR(50) NOT NULL,
jersey_no INT,
runs INT DEFAULT 0,
CONSTRAINT pk_squad PRIMARY KEY (id),
CONSTRAINT uq_squad_jersey UNIQUE (jersey_no),
CONSTRAINT ck_squad_runs CHECK (runs >= 0)
);
INSERT INTO squad (id, name, jersey_no, runs)
VALUES (1, 'Virat Kohli', 18, 750),
(2, 'Faf du Plessis', 13, 450);
SELECT * FROM squad;| id | name | jersey_no | runs |
|---|---|---|---|
| 1 | Virat Kohli | 18 | 750 |
| 2 | Faf du Plessis | 13 | 450 |
Now try to break the rules:
| Statement | Result |
|---|---|
INSERT ... VALUES (3, 'Rajat Patidar', 18, 300) | ❌ UNIQUE violated — jersey 18 is taken |
INSERT ... VALUES (3, 'Rajat Patidar', 97, -10) | ❌ CHECK violated — runs can't be negative |
INSERT ... VALUES (3, 'Rajat Patidar', 97, 300) | ✅ OK |
Example — FOREIGN KEY: linking players to teams
The practice database has a teams table whose primary key is team (RCB, MI, CSK, RR, DC, KKR, GT). A new contracts table can refer to it:
sql
CREATE TABLE contracts (
contract_id INT NOT NULL,
player_name VARCHAR(50) NOT NULL,
team VARCHAR(10) NOT NULL,
price_cr DECIMAL(5,2),
CONSTRAINT pk_contracts PRIMARY KEY (contract_id),
CONSTRAINT fk_contracts_team FOREIGN KEY (team) REFERENCES teams (team)
);
INSERT INTO contracts VALUES (1, 'Shubman Gill', 'GT', 16.50); -- ✅ GT exists in teams
INSERT INTO contracts VALUES (2, 'Unknown Star', 'XYZ', 1.00); -- ❌ XYZ does not existThe second insert fails with: The INSERT statement conflicted with the FOREIGN KEY constraint "fk_contracts_team".
Words to know:
- Parent table (referenced) —
teams. Child table (referencing) —contracts. - The foreign key also protects the parent: you cannot delete team
GTfromteams(orDROPtheteamstable) while contracts still point to it. - Options like
ON DELETE CASCADEtell SQL to delete the child rows automatically when the parent row is deleted.
Note (playground): SQLite only enforces foreign keys when they are switched on. The FOREIGN KEY example below switches them on for you behind the scenes, so it behaves like SQL Server.
Common mistakes
- ❌ Thinking UNIQUE = PRIMARY KEY. ✅ UNIQUE allows NULL and you can have many of them.
- ❌ A foreign key pointing to a column that is not a primary/unique key. ✅
REFERENCESmust target a PRIMARY KEY or UNIQUE column. - ❌ Different data types on the two sides (
INTvsVARCHAR). ✅ Make the foreign key column the same type as the parent column. - ❌ Inserting child rows before parent rows. ✅ Insert the team first, then the players/contracts.
- ❌
CHECK (runs > 0)when 0 is valid. ✅ Think about edge cases:CHECK (runs >= 0).
Interview tip
Q: What is referential integrity?
A: It is the guarantee that a relationship between two tables stays valid — every foreign key value in the child table matches an existing primary key value in the parent table. The FOREIGN KEY constraint enforces it by rejecting inserts/updates with non-existent parents and blocking deletes of parents that still have children.
Key points to remember
- UNIQUE blocks duplicate values; a table can have many UNIQUE constraints and they allow NULL.
- CHECK accepts only values for which its condition is true, e.g. CHECK (runs >= 0).
- FOREIGN KEY makes a column refer to the primary/unique key of another table — values must exist in the parent table.
- Referential integrity = every foreign key value matches an existing parent row.
- A foreign key also blocks deleting or dropping a parent that still has child rows (unless ON DELETE CASCADE is used).
- PRIMARY KEY = UNIQUE + NOT NULL, and only one per table.
- Name every constraint (uq_, ck_, fk_ prefixes) so errors are easy to read.
Try it yourself
UNIQUE and CHECK in action
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
FOREIGN KEY: contracts must point to a real team
This example runs a small setup step first — click to see it
PRAGMA foreign_keys = ON;
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Practice: add a CHECK for strike rate
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Revision Flashcards
Tap a card to flip it and see the answer.
