PostgreSQL

Installation

Installation - Fedora

Installation - Docker

Installation - Extension

Config - Server

Config - Server - postgresql.conf

Config - Server - pg_hba.conf

  • Location

    Fedora

    /var/lib/pgsql/data/pg_hba.conf

Config - Server - log

  • Location

    Fedora

    /var/lib/pgsql/log

Config - Enable TCP Connection

Change listen_addresses in postgresql.conf to desired IP to allow TCP connections. By default, only local connection via Unix domain socket is allowed.

Config - Enable authentication from remote IPs

Change pg_hba.conf to allow remote authentication.

Config - Client

Connection Strings

Environment Variables

JDBC

Solution Design

Fuzzy search

Full text search

Cheatsheet

psql - PostgreSQL interactive terminal

psql - Log in as the postgres superuser (root equivalent)

  • First time login after installation
  • Require the password of the current OS user
sudo -u postgres psql

psql - Connect to a database

# Default values can be omitted
PGPASSWORD=$database_password psql -h $database_host -p $database_port -U $database_user -d $database_name

or

Using PSQL_CONNECTION_STRING

export PSQL_CONNECTION_STRING="postgres:///${PGDATABASE}?user=${PGUSER}&password=${PGPASSWORD}&host=/var/run/postgresql/"
psql $PSQL_CONNECTION_STRING

psql - List all databases

\l

or

\list

psql - Change the current database

\c $database_name

psql - List all schemas in the current database

\dn+

psql - List all tables in the current database

\dt+

psql - List all tables from a specific schema in the current database

\dt+ $schema_name.*

psql - Show table schema

\d+ $table_name

or

SELECT *
FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog'
AND schemaname != 'information_schema';

psql - Run a SQL script

psql $PSQL_CONNECTION_STRING -f script.sql

psql - List all roles

\du

psql - List all installed extensions

\dx

SQL

  • exists is a boolean operator like a function

SQL - View server settings

SELECT * FROM postgres.pg_catalog.pg_settings

SQL - Create a new role

CREATE ROLE $role_name WITH PASSWORD '$password' LOGIN;

SQL - Create a database if it does not exist

SELECT 'CREATE DATABASE $db OWNER $role_name'
WHERE NOT EXISTS(SELECT FROM pg_database WHERE datname = '$db');

SQL - Add an identity column to a table

CREATE TABLE people (
    id bigint GENERATED ALWAYS AS IDENTITY,
    ...,
);

SQL - Drop a table if it exists

DROP TABLE IF EXISTS $schema.$table_name;

SQL - Delete all rows from a table only if the table exists

DELETE FROM $table_name
WHERE EXISTS (
  SELECT to_regclass('$schema.$table_name')
);

or

DELETE FROM $table_name
WHERE EXISTS (
  SELECT 1
  FROM information_schema.tables
  WHERE table_schema = '$schema'
  AND table_name = '$table_name'
);

SQL - Verify an extension is installed

CREATE EXTENSION IF NOT EXISTS $extension_name WITH SCHEMA $schema_name;
SELECT * FROM pg_extension WHERE extname = '$extension_name';

SQL - Verify pgvector extension is installed and functional

CREATE EXTENSION IF NOT EXISTS vector;
SELECT * FROM pg_extension WHERE extname = 'vector';
CREATE TABLE items (
  id SERIAL PRIMARY KEY,
  embedding VECTOR(3) -- Example for 3-dimensional vectors
);
 
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
 
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;

SQL - Generate random data

-- Fills the temp.users table with 10 million rows
CREATE SCHEMA IF NOT EXISTS temp;
DROP TABLE IF EXISTS temp.users;
 
BEGIN;
SET LOCAL statement_timeout = '120s';
 
-- Requires PostgreSQL 16+ for underscores
CREATE TABLE IF NOT EXISTS temp.users WITH
(
    autovacuum_enabled =
    FALSE
) AS
SELECT seq             AS id,
       'fname' || seq  AS first_name,
       'lname' || seq  AS last_name,
       'user_' || seq || '@' || (
           CASE (RANDOM() * 2):: INT
               WHEN 0 THEN 'gmail'
               WHEN 1 THEN 'hotmail'
               WHEN 2 THEN 'yahoo'
               END
           ) || '.com' AS email,
       CASE (seq % 2)
           WHEN 0 THEN 'Driver'
           ELSE 'Rider'
           END         AS type,
       NOW()           AS created_at,
       NOW()           AS updated_at
FROM GENERATE_SERIES(1, 10_000_000) seq;
COMMIT;
 
-- Update VM and stats
VACUUM ( ANALYZE ) temp.users;

Troubleshooting

Networking

  • Capture packets with Wireshark and use filter pgsql to see PostgreSQL traffic

Tooling

Tooling - PostgREST