Getting Started
Creating Tables
Design PostgreSQL tables with the right data types, constraints, and relationships.
PostgreSQL Data Types
PostgreSQL has a rich type system:
Numbers: SMALLINT, INTEGER, BIGINT, DECIMAL, NUMERIC, REAL, DOUBLE PRECISION
Text: CHAR(n), VARCHAR(n), TEXT
Date/Time: DATE, TIME, TIMESTAMP, TIMESTAMPTZ, INTERVAL
Boolean: BOOLEAN
Identifiers: UUID, SERIAL, BIGSERIAL
JSON: JSON, JSONB (binary, indexed)
Arrays: INTEGER[], TEXT[]
Constraints
NOT NULL— column cannot be nullUNIQUE— all values must be uniquePRIMARY KEY— unique + not nullFOREIGN KEY— references another tableCHECK— custom validationDEFAULT— default value
Example
sql
-- Create tables with proper types and constraints
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(50) UNIQUE NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
age INTEGER CHECK (age >= 0 AND age <= 150),
role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('user', 'admin', 'moderator')),
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
-- Posts table with foreign key
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(200) NOT NULL,
slug VARCHAR(200) UNIQUE NOT NULL,
content TEXT,
tags TEXT[], -- array type
metadata JSONB, -- binary JSON
views INTEGER DEFAULT 0,
published BOOLEAN DEFAULT FALSE,
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create indexes for performance
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_published ON posts(published) WHERE published = TRUE;
CREATE INDEX idx_posts_tags ON posts USING GIN(tags);
-- Full text search index
CREATE INDEX idx_posts_fts ON posts
USING GIN(to_tsvector('english', title || ' ' || COALESCE(content, '')));Want to run this code interactively?
Try in Compiler