FOREIGN KEY
A FOREIGN KEY constraint links a column (or set of columns) in one table to the primary key, or another unique constraint, of a second table. Its job is to enforce referential integrity — guaranteeing that a value stored in the foreign key column always corresponds to a real, existing row in the referenced table.
Worked example: orders and customers
CREATE TABLE customers ( customer_id INT PRIMARY KEY, name VARCHAR(100) NOT NULL ); CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT NOT NULL, order_date DATE NOT NULL, FOREIGN KEY (customer_id) REFERENCES customers(customer_id) );
With this foreign key in place, the database will refuse to insert an order whose customer_id does not already exist in the customers table:
-- Fails: no customer with id 999 INSERT INTO orders (order_id, customer_id, order_date) VALUES (501, 999, '2024-05-01');
ERROR: insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey" DETAIL: Key (customer_id)=(999) is not present in table "customers".
Without this constraint, nothing would stop an application bug from inserting an order that points at a customer who does not exist — an orphaned row that silently corrupts any report or join relying on that relationship.
ON DELETE and ON UPDATE actions
The ON DELETE and ON UPDATE clauses tell the database how to handle changes to the parent row instead of simply rejecting them:
Action | Behavior on delete/update of the parent row |
|---|---|
RESTRICT (or NO ACTION, the default in most systems) | Reject the delete/update if any dependent rows still reference the parent row. |
CASCADE | Automatically delete (or update) the dependent rows along with the parent row. |
SET NULL | Set the foreign key column in dependent rows to NULL when the parent row is deleted/updated (requires the column to allow NULL). |
SET DEFAULT | Set the foreign key column in dependent rows to its DEFAULT value. |
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);With ON DELETE CASCADE, deleting a customer automatically deletes every one of their orders too — convenient, but destructive, since a single DELETE on customers can silently remove a large amount of related data.