Dataslope logoDataslope

Creating Tables

How to define a table's shape with CREATE TABLE, choose columns and types, and add simple rules that keep your data clean.

So far, the runnable blocks have quietly created tables for you with their initSql. Now you will create them yourself. Defining a table is how you give a database its structure — and it is more interesting than it sounds, because a table definition is really a set of promises about your data.

The CREATE TABLE statement

To make a table, you list its columns and each column's type inside CREATE TABLE:

SQL
PostgreSQL 17

Read it as a sentence: "Create a table called books with an integer id, a text title, a text author, and an integer year." The parentheses hold a comma-separated list of column_name TYPE pairs. That is the core of the whole statement.

Adding rules with constraints

Beyond a name and type, each column can carry constraints — rules the database enforces on every row. They turn a table from a loose grid into a guardrail for clean data. The common ones:

ConstraintMeaning
PRIMARY KEYUniquely identifies each row (unique + not null)
NOT NULLThis column can never be empty
UNIQUENo two rows may share this value
DEFAULT xIf no value is given, use x
CHECK (...)The value must satisfy a condition

Here is the same table, upgraded with rules that express real intent about the data:

SQL
PostgreSQL 17

Look at the result: even though we never supplied a genre, the row has Unknown, because of DEFAULT 'Unknown'. The table filled in the blank for us. Meanwhile title NOT NULL guarantees no book can ever be saved without a title, and CHECK (year > 0) blocks nonsensical years.

Constraints are documentation that bites

A good set of constraints tells the next person (and future you) what the data means — "a book must have a title," "a year is positive." Unlike a comment, the database actually enforces these promises, so they can never quietly drift out of date.

Auto-generating ids with SERIAL

Typing id values by hand is tedious and error-prone. PostgreSQL can generate them for you. Declaring a column as SERIAL makes the database assign the next number automatically on each insert:

SQL
PostgreSQL 17

This is the everyday way to create surrogate primary keys (from the Primary Keys page): a SERIAL PRIMARY KEY gives every row a guaranteed-unique id without you tracking the numbers yourself.

Removing a table

To delete an entire table and all its rows, use DROP TABLE. Handle with care — it is permanent.

DROP TABLE books;

Check your understanding

QuestionSelect one

What does CREATE TABLE do?

It inserts new rows into an existing table.

It defines a new table's structure — its name, columns, and their types and rules.

It permanently deletes a table.

It runs a search over the data.

QuestionSelect one

A column is declared genre TEXT DEFAULT 'Unknown'. A row is inserted without providing a genre. What is stored?

The row is rejected because genre is missing.

An empty/null genre.

The value 'Unknown', because DEFAULT supplies it when no value is given.

A random genre chosen by the database.

QuestionSelect one

Why is declaring a column as SERIAL PRIMARY KEY so common?

It encrypts the column for security.

It sorts the table by that column automatically.

PostgreSQL automatically assigns the next unique number, giving each row a stable surrogate key without manual tracking.

It allows the column to store text and numbers together.

On this page