PostgreSQL Basics
10 examples to get you started with PostgreSQL fundamentals - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with PostgreSQL fundamentals - 7 basic and 3 intermediate.
Install PostgreSQL 18 locally or use Docker. You need psql and superuser access to create sample objects.
# Local dev with Docker (PostgreSQL 18)
docker run -d --name pg18 -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:18
psql postgres://postgres:dev@localhost:5432/postgresEvery session attaches to exactly one database on the cluster.
\c postgres
SELECT current_database(), current_user, version();\c dbname in psql switches databases without reconnecting the client binaryversion() returns the server build; pin client tools to the same major when possibleRelated: Postgres Architecture - processes behind the connection
Schemas group tables, views, and functions. public is the default schema.
CREATE SCHEMA app AUTHORIZATION postgres;
CREATE TABLE app.customers (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
email text NOT NULL UNIQUE,
created_at timestamptz NOT NULL DEFAULT now()
);
INSERT INTO app.customers (email) VALUES ('ada@example.com');Readable SQL lists columns and filters early.
SELECT id, email, created_at
FROM app.customers
WHERE email LIKE '%@example.com'
ORDER BY created_at DESC
LIMIT 10;SELECT * in application code; schema changes break clients silentlyLIMIT without ORDER BY returns an arbitrary row setRelated: SQL Querying Basics
System catalogs describe every object in the cluster.
SELECT n.nspname AS schema, c.relname AS table_name, c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'app' AND c.relkind = 'r'
ORDER BY 1, 2;pg_class + pg_namespace are the low-level table registryinformation_schema offers SQL-standard views with less detailRelated: System Catalogs
ACID transactions group changes into one atomic unit.
BEGIN;
INSERT INTO app.customers (email) VALUES ('grace@example.com');
UPDATE app.customers SET email = lower(email) WHERE email = 'grace@example.com';
COMMIT;BEGINROLLBACK undoes work in the current transactionRelated: Transactions Basics
B-tree indexes accelerate equality and range predicates on columns.
CREATE INDEX customers_created_at_idx
ON app.customers (created_at DESC);
EXPLAIN (ANALYZE, BUFFERS)
SELECT id FROM app.customers
WHERE created_at > now() - interval '7 days';EXPLAIN ANALYZE executes the query and shows actual timingsRelated: Indexes Basics
Extensions ship optional features as controlled modules.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
SELECT gen_random_uuid();pg_extensionCREATE on the databaseUnqualified names resolve via search_path. Misconfiguration causes wrong-table bugs.
SHOW search_path;
SET search_path = app, public;
SELECT email FROM customers LIMIT 1;
-- Safer in apps: always schema-qualify
SELECT email FROM app.customers LIMIT 1;"$user", public - empty schemas can surprise new rolespublic for multi-tenant data without RLSRelated: Database, Schema & Search Path
Quick catalog queries expose connections, bloat hints, and version.
SELECT count(*) AS backends FROM pg_stat_activity;
SELECT datname, numbackends, xact_commit, blks_read
FROM pg_stat_database
WHERE datname = current_database();pg_stat_activity lists live sessions and wait eventspg_stat_database aggregates commits, reads, and conflicts per databaseRelated: Postgres Architecture
Store instants in UTC; convert at the application edge.
ALTER TABLE app.customers
ADD COLUMN last_login_at timestamptz;
UPDATE app.customers
SET last_login_at = now()
WHERE email = 'ada@example.com';
SELECT email, last_login_at AT TIME ZONE 'America/New_York' AS login_ny
FROM app.customers;timestamptz stores UTC internally; display depends on session TimeZonetimestamp without time zone for real-world event timesRelated: Date, Time & Timestamptz
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 16, 2026