PostgreSQL System Tables

Explore database metadata and system information

🗄️ What are System Tables?

System tables store metadata about your database structure, including information about tables, columns, indexes, users, and permissions. They help you understand and manage your database configuration.


-- Query system tables
SELECT table_name 
FROM information_schema.tables
WHERE table_schema = 'public';
                                    

Output:

table_name
-----------
users
products
orders

Important System Catalogs

📊

pg_tables

Information about all tables

SELECT * FROM pg_tables
WHERE schemaname = 'public';
🔍

pg_indexes

Details about database indexes

SELECT * FROM pg_indexes
WHERE tablename = 'users';
👥

pg_user

Database user information

SELECT usename, usesuper
FROM pg_user;
💾

pg_database

List of all databases

SELECT datname
FROM pg_database;

🔹 information_schema.tables

The information_schema.tables view provides standardized information about all tables in the database. It's portable across different SQL databases and easy to query.

-- List all tables in public schema
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;

-- Get table details
SELECT 
    table_catalog,
    table_schema,
    table_name,
    table_type
FROM information_schema.tables
WHERE table_schema NOT IN ('pg_catalog', 'information_schema');

-- Count tables by schema
SELECT 
    table_schema,
    COUNT(*) as table_count
FROM information_schema.tables
GROUP BY table_schema;

Output:

table_name | table_type
-----------+------------
orders     | BASE TABLE
products   | BASE TABLE
users      | BASE TABLE

🔹 information_schema.columns

This view contains information about all columns in database tables, including data types, nullability, and default values. Essential for understanding table structure.

-- List all columns in a table
SELECT 
    column_name,
    data_type,
    is_nullable,
    column_default
FROM information_schema.columns
WHERE table_name = 'users'
ORDER BY ordinal_position;

-- Find columns by data type
SELECT 
    table_name,
    column_name,
    data_type
FROM information_schema.columns
WHERE data_type = 'integer'
AND table_schema = 'public';

-- Get column character limits
SELECT 
    column_name,
    character_maximum_length
FROM information_schema.columns
WHERE table_name = 'products'
AND character_maximum_length IS NOT NULL;

Output:

column_name | data_type | is_nullable
------------+-----------+-------------
id          | integer   | NO
username    | varchar   | NO
email       | varchar   | YES
created_at  | timestamp | YES

🔹 pg_tables

pg_tables provides PostgreSQL-specific information about tables, including ownership and tablespace details. More detailed than information_schema for PostgreSQL-specific features.

-- List all user tables
SELECT 
    schemaname,
    tablename,
    tableowner,
    hasindexes,
    hasrules
FROM pg_tables
WHERE schemaname = 'public';

-- Find tables with indexes
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
AND hasindexes = true;

-- Get table ownership info
SELECT 
    tablename,
    tableowner
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename;

Output:

tablename | tableowner | hasindexes
----------+------------+------------
users     | postgres   | t
products  | postgres   | t
orders    | postgres   | t

🔹 pg_indexes

pg_indexes shows all indexes in the database with their definitions. Use this to understand index structure and optimize query performance.

-- List all indexes
SELECT 
    schemaname,
    tablename,
    indexname,
    indexdef
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY tablename, indexname;

-- Find indexes on specific table
SELECT 
    indexname,
    indexdef
FROM pg_indexes
WHERE tablename = 'users';

-- List unique indexes
SELECT 
    tablename,
    indexname
FROM pg_indexes
WHERE indexdef LIKE '%UNIQUE%'
AND schemaname = 'public';

Output:

tablename | indexname        | indexdef
----------+------------------+---------------------------
users     | users_pkey       | CREATE UNIQUE INDEX...
users     | idx_users_email  | CREATE INDEX...

🔹 pg_constraint

pg_constraint contains information about all constraints including primary keys, foreign keys, unique constraints, and check constraints in your database.

-- List all constraints
SELECT 
    conname as constraint_name,
    contype as constraint_type,
    conrelid::regclass as table_name
FROM pg_constraint
WHERE connamespace = 'public'::regnamespace;

-- Find foreign key constraints
SELECT 
    tc.table_name,
    kcu.column_name,
    ccu.table_name AS foreign_table_name,
    ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
    ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
    ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY';

-- List primary keys
SELECT 
    tc.table_name,
    kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
    ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'PRIMARY KEY';

Output:

constraint_name | constraint_type | table_name
----------------+-----------------+------------
users_pkey      | p               | users
orders_user_fk  | f               | orders

🔹 pg_stat_activity

pg_stat_activity shows current database connections and running queries. Essential for monitoring database activity and troubleshooting performance issues.

-- View active connections
SELECT 
    pid,
    usename,
    application_name,
    client_addr,
    state,
    query
FROM pg_stat_activity
WHERE state = 'active';

-- Count connections by database
SELECT 
    datname,
    COUNT(*) as connection_count
FROM pg_stat_activity
GROUP BY datname;

-- Find long-running queries
SELECT 
    pid,
    now() - query_start as duration,
    query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > interval '5 minutes';

-- Kill a specific connection
-- SELECT pg_terminate_backend(pid)
-- WHERE pid = 12345;

Output:

pid   | usename  | state  | query
------+----------+--------+------------------
12345 | postgres | active | SELECT * FROM...

🔹 pg_database

pg_database contains information about all databases in the PostgreSQL cluster:

-- List all databases
SELECT 
    datname as database_name,
    pg_size_pretty(pg_database_size(datname)) as size,
    datcollate as collation,
    datconnlimit as connection_limit
FROM pg_database
ORDER BY datname;

-- Get current database info
SELECT 
    current_database() as current_db,
    current_schema() as current_schema;

-- Database size statistics
SELECT 
    datname,
    pg_database_size(datname) as size_bytes,
    pg_size_pretty(pg_database_size(datname)) as size
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

Output:

database_name | size    | connection_limit
--------------+---------+-----------------
myapp_db      | 125 MB  | -1
postgres      | 8 MB    | -1

🔹 Useful System Queries

Common queries for database administration and monitoring:

-- Get table sizes
SELECT 
    schemaname,
    tablename,
    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

-- List all sequences
SELECT sequence_name
FROM information_schema.sequences
WHERE sequence_schema = 'public';

-- View all views
SELECT table_name
FROM information_schema.views
WHERE table_schema = 'public';

-- Check database version
SELECT version();

-- Get server settings
SELECT name, setting, unit
FROM pg_settings
WHERE name IN ('max_connections', 'shared_buffers', 'work_mem');

🧠 Test Your Knowledge

Which system view shows column information?