SQL / CHAPTER 04

Keys, constraints, and valid rows

Intermediate

Encode data rules that every writer must respect.

By the end of this chapter

  • Distinguish keys from ordinary attributes
  • Combine NOT NULL with value checks
  • Model references explicitly

The idea

A schema defines more than column names. A key identifies a row, a UNIQUE constraint prevents duplicate accepted keys, and a foreign key describes a relationship to another table. These constraints protect against invalid writes from every application path, not just one form. Choose a stable identifier instead of assuming a mutable display name will remain unique forever.

NULL requires special care in constraints. In SQLite, a CHECK constraint rejects a zero result but does not reject a NULL result. A nonnegative required quantity therefore needs NOT NULL as well as CHECK(quantity >= 0). SQLite foreign-key enforcement must also be enabled for the connection when it is needed. State the intended deletion and update policies rather than assuming every related row should disappear automatically.

SQL example
CREATE TABLE stock(id INTEGER PRIMARY KEY, quantity INTEGER NOT NULL CHECK(quantity >= 0));
INSERT INTO stock(id,quantity) VALUES(1,0),(2,4);
SELECT id,quantity FROM stock ORDER BY id;
Result
id | quantity
1 | 0
2 | 4

Zero is a permitted quantity; the combination of constraints excludes both missing and negative quantities.

Try it yourself

Design a required unique external code and a required nonnegative balance, then list one failing insert per rule.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

Open SQL coding challenges

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which definition requires a nonnegative quantity and rejects missing values in SQLite?