🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Management / Database Administration › Relational Design & Normalization › Lesson 6
TEC-DATA86-02 · Lesson 6 · 14 clock hours · lab

Keys, Constraints, and Referential Integrity in SQL DDL

Objective. Students will write DDL statements (CREATE TABLE, ALTER TABLE) that implement primary keys, foreign keys, unique constraints, check constraints, and NOT NULL constraints in PostgreSQL, and verify that the database engine enforces each constraint.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Keys, Constraints, and Referential Integrity in SQL DDL

Constraints are rules the database engine enforces automatically to keep data accurate and consistent. Writing them into your DDL is far more reliable than depending on application code alone. This lesson covers the five constraint types you will use most often in PostgreSQL, how to write them, and how the engine reports violations.

Primary Keys

A primary key uniquely identifies every row in a table. It combines two implicit rules: the column(s) must be NOT NULL, and the value(s) must be unique across all rows. Each table may have only one primary key.

```sql

CREATE TABLE customer (

customer_id SERIAL PRIMARY KEY,

last_name VARCHAR(60) NOT NULL,

email VARCHAR(120) NOT NULL

);

```

For a composite key, list all columns in a table-level constraint:

```sql

CREATE TABLE order_line (

order_id INT NOT NULL,

line_number INT NOT NULL,

product_id INT NOT NULL,

quantity INT NOT NULL,

PRIMARY KEY (order_id, line_number)

);

```

Foreign Keys and Referential Integrity

A foreign key links a column in one table (the child) to the primary key of another table (the parent). PostgreSQL will reject any INSERT or UPDATE that would create an orphan row — a child row with no matching parent.

```sql

CREATE TABLE "order" (

order_id SERIAL PRIMARY KEY,

customer_id INT NOT NULL

REFERENCES customer(customer_id)

ON DELETE RESTRICT

ON UPDATE CASCADE,

order_date DATE NOT NULL

);

```

`ON DELETE RESTRICT` prevents deleting a customer who still has orders. `ON UPDATE CASCADE` automatically updates the child column if the parent key value changes. Choose these actions deliberately — they are part of your design.

You can also add a foreign key after the table exists using ALTER TABLE:

```sql

ALTER TABLE order_line

ADD CONSTRAINT fk_order_line_order

FOREIGN KEY (order_id)

REFERENCES "order"(order_id)

ON DELETE CASCADE;

```

UNIQUE Constraints

A UNIQUE constraint lets columns other than the primary key serve as alternate keys. Unlike a primary key, a unique column may contain NULL (PostgreSQL treats each NULL as distinct from every other NULL).

```sql

ALTER TABLE customer

ADD CONSTRAINT uq_customer_email UNIQUE (email);

```

NOT NULL Constraints

A NOT NULL constraint prevents a column from ever holding a NULL value. Apply it to any attribute that must always have a value. It is written inline with the column definition and cannot be added at the table level.

```sql

last_name VARCHAR(60) NOT NULL

```

CHECK Constraints

A CHECK constraint evaluates a Boolean expression before every INSERT or UPDATE. If the expression returns FALSE the operation is rejected; if it returns TRUE or NULL the row is accepted.

```sql

CREATE TABLE order_line (

order_id INT NOT NULL,

line_number INT NOT NULL,

product_id INT NOT NULL,

quantity INT NOT NULL CHECK (quantity > 0),

unit_price NUMERIC(10,2) NOT NULL CHECK (unit_price >= 0),

PRIMARY KEY (order_id, line_number)

);

```

Name your check constraints so error messages identify them clearly:

```sql

CONSTRAINT chk_quantity_positive CHECK (quantity > 0)

```

Verifying Constraints in psql

Use `\d tablename` in psql to see the column definitions and all constraints for a table. To query the catalog directly:

```sql

SELECT constraint_name, constraint_type

FROM information_schema.table_constraints

WHERE table_name = 'order_line';

```

This is the same query your instructor will use to grade your work.

Reading Error Messages

When a constraint fires, PostgreSQL returns a structured error. Learn to read it:

Record the full error text in your lab log exactly as it appears. The DETAIL line usually names the conflicting value.

Safety and Best Practices in the Lab

Data integrity failures in production systems can cause serious business harm — lost orders, double-billing, or orphaned financial records. Treat constraint design as a safety practice, not just a syntax exercise.

In the lab environment:

These habits apply equally to professional environments where mishandling data may violate privacy regulations.

Key terms10

Primary KeyA column or combination of columns whose values uniquely identify every row in a table; implicitly NOT NULL and UNIQUE.
Foreign KeyA column (or set of columns) in a child table that references the primary key of a parent table, enforcing referential integrity.
Referential IntegrityThe guarantee that every foreign key value in a child table matches an existing primary key value in the parent table, with no orphan rows.
CHECK ConstraintA constraint that evaluates a Boolean expression on a column value before each INSERT or UPDATE, rejecting rows where the expression is FALSE.
NOT NULL ConstraintA column-level rule that prevents a NULL value from ever being stored in that column.
UNIQUE ConstraintA rule that requires every non-NULL value in a column or column combination to appear no more than once in the table.
DDL (Data Definition Language)The subset of SQL used to create, modify, and drop database objects; includes CREATE TABLE, ALTER TABLE, and DROP TABLE.
ALTER TABLEA DDL statement that modifies an existing table's structure, such as adding a column, dropping a constraint, or adding a new constraint.
information_schemaA standard set of read-only views defined by the SQL standard and implemented in PostgreSQL that describe database objects, including tables, columns, and constraints.
Orphan RowA child row whose foreign key value does not match any primary key value in the parent table; PostgreSQL prevents this with a foreign key constraint.
In class: Guided lab: instructor demonstrates creating a normalized three-table schema (customer, order, order_line) in PostgreSQL using psql, defining all constraints inline and then adding one with ALTER TABLE; students follow along in their own psql session. · Constraint-testing lab: students insert rows that intentionally violate each constraint type (duplicate PK, null in NOT NULL column, orphan FK, check violation), observe the error messages, and record results in a lab log. · Schema build: students translate their normalized retail-store schema from Lesson 3 into a complete set of CREATE TABLE DDL statements in PostgreSQL with all constraints and confirm all tables are created with correct structure using \\d in psql.
Materials: PostgreSQL installed on lab workstations or cloud sandbox, psql command-line client, DDL reference (PostgreSQL documentation Chapter 5), lab log template
Check: Instructor queries information_schema.table_constraints and information_schema.columns to verify each required constraint exists. Pass: all primary keys, at least one foreign key per relationship, and at least one check constraint present; all constraint-test errors correctly recorded in lab log.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

PostgreSQL CE — DDL and constraints
1. A student writes `quantity INT NOT NULL CHECK (quantity > 0)`. A co-worker inserts a row with `quantity = 0`. What happens?
PostgreSQL CE — DDL and constraints
2. Which DDL statement correctly adds a named foreign key constraint to an existing table?
PostgreSQL CE — referential integrity
3. You delete a row from the `customer` table. The `"order"` table has `ON DELETE RESTRICT` on its customer_id foreign key. What does PostgreSQL do?
PostgreSQL CE — DDL and constraints
4. A table has `email VARCHAR(120) NOT NULL`. A user runs `INSERT INTO customer (last_name) VALUES ('Smith');` without supplying email. What error category will PostgreSQL report?
PostgreSQL CE — system catalog and administration
5. Which view in the `information_schema` would you query to confirm that a CHECK constraint named `chk_quantity_positive` exists on the `order_line` table?
PostgreSQL CE — relational design
6. A composite primary key is needed on (order_id, line_number) in the order_line table. How must it be defined?
DAMA CDMP — data quality
7. In the context of the DAMA CDMP data management framework, enforcing referential integrity through database constraints is primarily an example of which practice area?
PostgreSQL CE — referential integrity
8. A student inserts a row into `order_line` with an `order_id` value that does not exist in the `"order"` table. The foreign key constraint is active. What will PostgreSQL return?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.