SQL, Refreshed
Tables, types & constraints
Lesson 1 of 5
What you'll learn
- Define a table with
CREATE TABLEand column types - Use
PRIMARY KEY,NOT NULL, andUNIQUEto enforce rules - See constraints as guarantees the database itself protects
A table is a set of rows, where every row has the same typed columns. You describe the shape once with CREATE TABLE, and Postgres enforces it on every insert forever after.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
name TEXT,
age INTEGER
);
Each column has a type: INTEGER for whole numbers, TEXT for strings, BOOLEAN, TIMESTAMP, and many more. Try to store the wrong kind of value and the insert fails — the type is a promise about what lives there.
Constraints are guarantees
A constraint is a rule the database refuses to violate. PRIMARY KEY means this column uniquely identifies the row (and is never null). NOT NULL means a value is required. UNIQUE means no two rows may share that value.
INSERT INTO users (email, name) VALUES ('ada@example.com', 'Ada');
-- A second insert with the same email is REJECTED by UNIQUE.
The point is that these rules live in the database, not in your application code. Even a buggy app or a manual query can't sneak past them.
SERIAL is auto-incrementing
SERIAL isn't really a type — it's shorthand for an INTEGER column backed by a sequence that hands out 1, 2, 3… automatically, so you never assign id yourself.
A CREATE TABLE statement is really just a builder: you name the table, then accumulate column definitions. The challenge builds exactly that.
Run it. Each method call adds a column; build() emits the CREATE TABLE string.
Next: pulling rows back out with SELECT.
Sign in to save your progress across devices.