CREATE TABLE orders ( id BIGSERIAL PRIMARY KEY, quantity INT NOT NULL, unit_price NUMERIC(10,2) NOT NULL, -- Stored generated column total NUMERIC(10,2) GENERATED ALWAYS AS (quantity * unit_price) STORED);
CREATE TABLE reservations ( id BIGSERIAL PRIMARY KEY, room_id INT NOT NULL, during TSTZRANGE NOT NULL, CONSTRAINT reservations_no_overlap EXCLUDE USING gist (room_id WITH =, during WITH &&));
-- B-tree (default)CREATE INDEX idx_users_email ON users(email);-- Descending orderCREATE INDEX idx_orders_date ON orders(created_at DESC);-- Multiple columnsCREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
-- Hash (equality only)CREATE INDEX idx_users_email_hash ON users USING hash(email);-- GIN (arrays, JSONB, full-text)CREATE INDEX idx_products_tags ON products USING gin(tags);CREATE INDEX idx_users_data ON users USING gin(metadata jsonb_path_ops);-- GiST (geometric, range, full-text)CREATE INDEX idx_locations ON places USING gist(location);-- BRIN (very large tables, sorted data)CREATE INDEX idx_logs_time ON logs USING brin(created_at);-- SP-GiST (non-balanced data)CREATE INDEX idx_ips ON connections USING spgist(ip_address inet_ops);
-- Only index active usersCREATE INDEX idx_users_active ON users(email) WHERE status = 'active';-- Only index unprocessed ordersCREATE INDEX idx_orders_pending ON orders(created_at) WHERE processed_at IS NULL;
-- Index on lowercase emailCREATE INDEX idx_users_email_lower ON users(lower(email));-- Index on JSONB fieldCREATE INDEX idx_users_city ON users((data->>'city'));-- Index on date partCREATE INDEX idx_orders_month ON orders(date_trunc('month', created_at));
CREATE OR REPLACE FUNCTION update_updated_at()RETURNS TRIGGER AS $$BEGIN NEW.updated_at = NOW(); RETURN NEW;END;$$ LANGUAGE plpgsql;CREATE OR REPLACE FUNCTION get_user_orders(p_user_id BIGINT)RETURNS TABLE(order_id BIGINT, total NUMERIC) AS $$BEGIN RETURN QUERY SELECT id, total FROM orders WHERE user_id = p_user_id;END;$$ LANGUAGE plpgsql STABLE;
CREATE FUNCTION example()RETURNS void AS $$ -- function body$$ LANGUAGE plpgsqlVOLATILE -- Can modify data (default)-- STABLE -- Returns same result for same args in same statement-- IMMUTABLE -- Returns same result for same args alwaysSTRICT -- Returns NULL if any arg is NULLSECURITY DEFINER -- Runs with function owner's permissionsPARALLEL SAFE; -- Can run in parallel query
-- Before insert/updateCREATE TRIGGER update_users_timestamp BEFORE INSERT OR UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at();-- After insertCREATE TRIGGER audit_user_creation AFTER INSERT ON users FOR EACH ROW EXECUTE FUNCTION log_user_created();
CREATE TYPE order_status AS ENUM ( 'pending', 'confirmed', 'shipped', 'delivered', 'cancelled');-- Use in tableCREATE TABLE orders ( id BIGSERIAL PRIMARY KEY, status order_status NOT NULL DEFAULT 'pending');
CREATE TYPE address AS ( street VARCHAR(255), city VARCHAR(100), state VARCHAR(50), country VARCHAR(100), postal_code VARCHAR(20));-- Use in tableCREATE TABLE customers ( id BIGSERIAL PRIMARY KEY, billing_address address, shipping_address address);
CREATE DOMAIN email_address AS VARCHAR(255) CHECK (VALUE ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');CREATE DOMAIN positive_int AS INTEGER CHECK (VALUE > 0);-- Use in tableCREATE TABLE users ( id BIGSERIAL PRIMARY KEY, email email_address NOT NULL, age positive_int);
-- Common extensionsCREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generationCREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- Cryptographic functionsCREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- Trigram similarityCREATE EXTENSION IF NOT EXISTS "btree_gin"; -- GIN for scalarsCREATE EXTENSION IF NOT EXISTS "btree_gist"; -- GiST for scalarsCREATE EXTENSION IF NOT EXISTS "hstore"; -- Key-value storeCREATE EXTENSION IF NOT EXISTS "citext"; -- Case-insensitive textCREATE EXTENSION IF NOT EXISTS "postgis"; -- Geographic objectsCREATE EXTENSION IF NOT EXISTS "timescaledb"; -- Time-series
-- Standalone sequenceCREATE SEQUENCE order_number_seq START WITH 1000 INCREMENT BY 1 NO MAXVALUE CACHE 10;-- Use in tableCREATE TABLE orders ( id BIGSERIAL PRIMARY KEY, order_number BIGINT NOT NULL DEFAULT nextval('order_number_seq'));
COMMENT ON TABLE users IS 'Application users with authentication information';COMMENT ON COLUMN users.status IS 'Account status: active, suspended, or deleted';COMMENT ON INDEX idx_users_email IS 'Index for email lookups during authentication';COMMENT ON FUNCTION update_updated_at() IS 'Trigger function to update updated_at timestamp';