September 1, 2026
5 min read
PostgreSQL — Overview
What Is PostgreSQL
PostgreSQL is an open-source object-relational database focused on reliability and flexibility. In practice, it lets you use classic SQL tables and modern data styles (JSON, full-text search, geospatial, vectors) in one system.
Why PostgreSQL
Strength
Detail
ACID compliance
Transactions are safe: COMMIT saves, ROLLBACK cancels
SQL standard
Strong SQL support for joins, analytics, and constraints
Extensibility
Extensions add features: pgvector, PostGIS, pg_cron
JSON support
jsonb works well with indexes for document-like data
Concurrency
Many reads/writes at once without frequent lock pain
Ecosystem
Mature tools, cloud-managed options (RDS, Cloud SQL, Supabase, Neon)
Open source
No vendor lock-in, permissive license
How It Works in Daily Use
App / psql sends SQL
│
├── PostgreSQL validates query and permissions
├── Builds execution plan
├── Reads/writes data
└── Returns rows or status
This guide stays at the practical SQL/operations level and intentionally skips internal process architecture details.
PostgreSQL vs Alternatives
Aspect
PostgreSQL
MySQL
SQLite
MongoDB
Type
Object-relational
Relational
Embedded relational
Document
ACID
Full
Full (InnoDB)
Full
Per-document
JSON support
jsonb (indexed)
JSON (limited)
JSON1 extension
Native (BSON)
Extensions
Rich (pgvector, PostGIS)
Limited
Minimal
Plugins
Scaling
Vertical + read replicas
Vertical + read replicas
Single file
Horizontal (sharding)
Best for
General purpose, analytics
Web apps, read-heavy
Embedded, mobile, tests
Flexible schema, prototyping
When to Choose PostgreSQL
Good Fit
Consider Alternative
Complex queries with joins
Simple key-value lookups → Redis
ACID transactions required
Schemaless rapid prototyping → MongoDB
Mix of SQL + JSON data
Embedded / mobile / serverless → SQLite
Full-text search (built-in tsvector)
Heavy search workload → Elasticsearch
Geospatial (PostGIS)
Graph traversal → Neo4j
Vector similarity (pgvector)
Dedicated vector infra at scale → Pinecone
Key Extensions
Extension
Purpose
pgvector
Vector similarity search (AI/LLM)
PostGIS
Geospatial data and queries
pg_stat_statements
Query performance statistics
pg_cron
Scheduled jobs inside PostgreSQL
pgcrypto
Encryption functions
uuid-ossp / gen_random_uuid()
UUID generation
hstore
Key-value pairs in a column
Section Map
File
Topics
01 — Commands & psql
Connection, navigation, psql shortcuts, import/export
02 — Schema & Data Types
Tables, columns, types, constraints, indexes
03 — Queries & Performance
EXPLAIN ANALYZE, indexing strategy, pagination, window function tips, anti-patterns
04 — Admin & Operations
Users, roles, backup, Docker setup, tuning
05 — Basic Query Commands
SQL cheat sheet: CRUD, filters, joins, CTEs, window functions, set ops, transactions
Cheat Sheet
psql & Connection (01 )
Task
Command
Connect
psql -U user -d db
Connection string
psql "postgresql://user:pass@host:5432/db"
List databases
\l
List tables
\dt / \dt+ (with sizes)
Describe table
\d tablename / \d+ (detailed)
List indexes
\di
Show timing
\timing
Export CSV
\copy (SELECT ...) TO 'file.csv' WITH CSV HEADER
Import CSV
\copy table FROM 'file.csv' WITH CSV HEADER
Run SQL file
psql -f file.sql
Quit
\q
Schema & DDL (02 )
Task
SQL
Create table
CREATE TABLE t (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, ...);
Add column
ALTER TABLE t ADD COLUMN col TEXT;
Drop column
ALTER TABLE t DROP COLUMN col;
Rename column
ALTER TABLE t RENAME COLUMN old TO new;
Add constraint
ALTER TABLE t ADD CONSTRAINT chk CHECK (col > 0);
Foreign key
col BIGINT REFERENCES other(id) ON DELETE CASCADE
Create index
CREATE INDEX idx ON t (col);
JSONB index
CREATE INDEX idx ON t USING gin (jsonb_col);
Partial index
CREATE INDEX idx ON t (col) WHERE active = true;
Create view
CREATE VIEW v AS SELECT ...;
Materialized view
CREATE MATERIALIZED VIEW v AS SELECT ...; REFRESH MATERIALIZED VIEW v;
Queries (05 )
Task
SQL
Filter
WHERE col IN (...) / BETWEEN / LIKE / ILIKE / IS NULL
Upsert
INSERT ... ON CONFLICT (col) DO UPDATE SET ...
Bulk insert
INSERT INTO t SELECT ... FROM ...
Update from join
UPDATE t SET col = s.val FROM source s WHERE s.id = t.id
Delete with join
DELETE FROM t USING other o WHERE t.fk = o.id
Union (dedup)
SELECT ... UNION SELECT ...
Union (keep all)
SELECT ... UNION ALL SELECT ...
Window rank
row_number() OVER (PARTITION BY col ORDER BY col)
Previous row
lag(col) OVER (ORDER BY col)
Conditional
CASE WHEN ... THEN ... ELSE ... END
Safe NULL
coalesce(col, default)
Cast
col::type or CAST(col AS type)
Truncate
TRUNCATE table RESTART IDENTITY CASCADE
Task
SQL
Explain query
EXPLAIN (ANALYZE, BUFFERS) SELECT ...
Filter JSONB
WHERE data @> '{"key": "val"}'
Array overlap
WHERE tags && ARRAY['a', 'b']
Full-text search
WHERE to_tsvector('english', body) @@ to_tsquery('term')
Cursor pagination
WHERE id > last_id ORDER BY id LIMIT n
Estimate row count
SELECT n_live_tup FROM pg_stat_user_tables WHERE relname = 't'
Admin & Ops (04 )
Task
Command
Create user
CREATE ROLE name WITH LOGIN PASSWORD '...';
Grant read-only
GRANT SELECT ON ALL TABLES IN SCHEMA public TO role;
Backup DB
pg_dump -U user -d db -Fc -f backup.dump
Restore DB
pg_restore -U user -d db --clean --if-exists backup.dump
Docker connect
docker compose exec db psql -U user -d db
Update stats
ANALYZE; / ANALYZE tablename;
Vacuum
VACUUM ANALYZE;
Active queries
SELECT pid, now()-query_start AS dur, query FROM pg_stat_activity WHERE state = 'active';
Kill query
SELECT pg_cancel_backend(pid);
Table size
SELECT pg_size_pretty(pg_total_relation_size('table'));
DB size
SELECT pg_size_pretty(pg_database_size('db'));
See also
databases
postgresql
sql