deskDBMSINSERT INTO books VALUES(2, 'Stardust', 'B2', 1999, 2);INSERT INTO books VALUES(4, NULL, 'B2', 1999, 2);INSERT INTO books VALUES(4, 'Stardust', 'B1', 1999, 2);INSERT INTO books VALUES(4, 'Stardust', 'B2', 0, 2);INSERT INTO books VALUES(4, 'Stardust', 'B2', 1999, 9);INSERT INTO books VALUES(4, 'Stardust', 'B2', 1999, 2);DELETE FROM authorsWHERE id = 2;id name1 Frank Herbert2 Neil Gaiman3 Louis Sachar1CREATE TABLE books (2 id integer PRIMARY KEY,3 title text NOT NULL,4 shelf text UNIQUE,5 year integer CHECK (year > 0),6 author_id integer7 REFERENCES authors (id)8);id title shelf year author_id1 Dune A1 1965 12 Coraline B1 2002 23 Holes C1 1998 34 Stardust B2 1999 2row
Back row: the front desk, the DBMS and the authors tableFront: the change sent, the table's rules, and the books tableEnvelope: the change; badge: refused or storedAt the back: the front desk that sends changes, the DBMS and the authors table. In front: the change sent this step, the books table definition with one rule per line, and the books table. The same new row, Stardust, is sent with one broken value at a time; the DBMS refuses each one until every rule passes. The foreign key links books to authors both ways: a book must point at a real author, and an author with books cannot be deleted. Each try in the figure breaks exactly one rule. A row that breaks several gets one error: PostgreSQL stops at the first rule it finds broken.

Rules in the table

  1. Constraints are rules written into a table’s definition. The DBMS checks every insert, update and delete against them. A change that breaks any rule is refused whole, so bad data never gets in, whichever program sends it.

One row, five rules

Keys link tables

What happens

;; step 1/8 · rules
the books table and its rules:
  CREATE TABLE books (
    id integer PRIMARY KEY,
    title text NOT NULL,
    shelf text UNIQUE,
    year integer CHECK (year > 0),
    author_id integer
      REFERENCES authors (id)
  );

PRIMARY KEY  one unique, non-empty id per row
NOT NULL     a value is required
UNIQUE       no two rows share a value
CHECK        a test every row must pass
REFERENCES   must match a row in another table

Each try in the figure breaks exactly one rule. A row that breaks several gets one error: PostgreSQL stops at the first rule it finds broken. A CHECK passes when its test is true or NULL, so CHECK (year > 0) lets a missing year through. Add NOT NULL as well to require one.