DataSkills Hub

PostgreSQL

PostgreSQL es una base de datos relacional robusta para almacenamiento y análisis de datos. Almacena metadatos de servicios, datos operacionales y tablas analíticas.

#Getting Started

#Conectarse a PostgreSQL

Desde el servidor vía usuario postgres

$ sudo -u postgres psql

Conectarse a una base de datos específica

$ psql -U usuario -h <tu-host> -p <puerto> -d nombre_db

Verificar versión instalada

$ psql --version
Comando Descripción
\l Listar todas las bases de datos
\c <db> Conectarse a una base de datos
\dt Listar tablas del esquema actual
\dn Listar esquemas
\du Listar roles/usuarios
\d <tabla> Describir estructura de una tabla
\d+ <tabla> Descripción detallada con tamaño
\conninfo Mostrar info de la conexión actual
\q Salir de psql

#Obtener ayuda

Comando Descripción
\h Ayuda sobre sintaxis SQL
\h SELECT Sintaxis específica del comando SELECT
\h CREATE TABLE Sintaxis de CREATE TABLE
\? Lista de comandos psql (meta-comandos)

#Opciones de conexión psql

Opción Ejemplo Descripción
[-d] <db> psql -d mydb Conectarse a una base
-U psql -U admin mydb Especificar usuario
-h -p psql -h <host> -p <puerto> mydb Host y puerto
-W psql -W mydb Forzar prompt de contraseña
-c psql -c '\dt' mydb Ejecutar un comando y salir
-f psql mydb -f script.sql Ejecutar archivo SQL
-l psql -l Listar bases de datos
-H psql -c "\l+" -H > dbs.html Salida en formato HTML

#Comandos psql

#Tablas y objetos

Comando Descripción
\dt Tablas del esquema actual
\dt *.* Tablas de todos los esquemas
\dt <schema>.* Tablas de un esquema específico
\di[S+] Índices
\ds[S+] Secuencias
\dv[S+] Vistas
\df[S+] Funciones
\dp Privilegios de acceso en tablas
\det[+] Tablas externas (foreign tables)
\dx[+] Extensiones instaladas

S: incluir objetos de sistema, +: detalle adicional

#Información del servidor

Comando Descripción
\l[+] Listar bases de datos
\dn[S+] Listar esquemas
\du[+] Listar roles
\dT[S+] Listar tipos de datos
\da[S] Listar agregados
\db[+] Listar tablespaces
\dL[S+] Listar lenguajes procedurales
\do[S] Listar operadores
\drds Configuraciones por rol/base

#Buffer de consultas

Comando Descripción
\e [FILE] Editar buffer de consulta (o archivo)
\ef [FUNC] Editar definición de función
\p Mostrar contenido del buffer
\r Limpiar el buffer
\s [FILE] Mostrar historial o guardar a archivo
\w FILE Escribir buffer a archivo

#Entrada/Salida

Comando Descripción
\copy ... Importar/exportar tabla (ver CSV abajo)
\i FILE Ejecutar archivo SQL
\o [FILE] Redirigir salida a archivo
\echo [STRING] Imprimir texto

#Formato de salida

Comando Descripción
\a Alternar alineado/no alineado
\H Alternar salida HTML
\x Alternar salida expandida (vertical)
\t Mostrar solo filas (sin headers)
\timing Alternar medición de tiempo

#Misceláneos psql

Comando Descripción
\cd [DIR] Cambiar directorio
\! [CMD] Ejecutar comando en shell
\! ls -l Listar archivos desde psql
\set NAME VALUE Establecer variable
\unset NAME Eliminar variable
\password [USER] Cambiar contraseña
\encoding [ENC] Ver/cambiar encoding del cliente

#Consultas SQL Esenciales

#Bases de datos

Crear base de datos

CREATE DATABASE analytics_db WITH OWNER db_admin;

Eliminar base de datos

DROP DATABASE IF EXISTS analytics_db;

Renombrar base de datos

ALTER DATABASE old_name RENAME TO new_name;

Ver base de datos actual

SELECT current_database();

#Esquemas

Crear esquema (cada servicio con su propio esquema)

CREATE SCHEMA IF NOT EXISTS airflow_metadata;
CREATE SCHEMA IF NOT EXISTS superset_data;
CREATE SCHEMA IF NOT EXISTS analytics;

Listar esquemas

SELECT schema_name
FROM information_schema.schemata;

Eliminar esquema

DROP SCHEMA IF EXISTS old_schema CASCADE;

#Tablas — DDL

Crear tabla

CREATE TABLE analytics.dim_clientes (
  id         SERIAL PRIMARY KEY,
  nombre     VARCHAR(100) NOT NULL,
  segmento   VARCHAR(50),
  created_at TIMESTAMP DEFAULT NOW()
);

Crear tabla con clave foránea

CREATE TABLE analytics.fact_ventas (
  id          SERIAL PRIMARY KEY,
  cliente_id  INT REFERENCES analytics.dim_clientes(id),
  monto       NUMERIC(12,2),
  fecha       DATE NOT NULL
);

Eliminar tabla

DROP TABLE IF EXISTS analytics.fact_ventas CASCADE;

#Tablas — ALTER

Agregar columna

ALTER TABLE analytics.dim_clientes
ADD COLUMN email VARCHAR(255);

Modificar tipo de columna

ALTER TABLE analytics.dim_clientes
ALTER COLUMN segmento TYPE VARCHAR(100);

Eliminar columna

ALTER TABLE analytics.dim_clientes
DROP COLUMN email;

Renombrar columna

ALTER TABLE analytics.dim_clientes
RENAME COLUMN segmento TO categoria;

#Consultas SELECT

Seleccionar todo

SELECT * FROM analytics.dim_clientes;

Filtrar con WHERE

SELECT nombre, segmento
FROM analytics.dim_clientes
WHERE segmento = 'Enterprise';

Ordenar y limitar

SELECT * FROM analytics.fact_ventas
ORDER BY fecha DESC
LIMIT 20;

Agregaciones

SELECT segmento, COUNT(*) AS total, SUM(monto) AS revenue
FROM analytics.fact_ventas v
JOIN analytics.dim_clientes c ON v.cliente_id = c.id
GROUP BY segmento
ORDER BY revenue DESC;

#DML — INSERT, UPDATE, DELETE

Insertar registros

INSERT INTO analytics.dim_clientes (nombre, segmento)
VALUES ('Acme Corp', 'Enterprise');

Insertar múltiples registros

INSERT INTO analytics.dim_clientes (nombre, segmento)
VALUES
  ('Cliente A', 'SMB'),
  ('Cliente B', 'Enterprise'),
  ('Cliente C', 'Gobierno');

Actualizar registros

UPDATE analytics.dim_clientes
SET segmento = 'VIP'
WHERE nombre = 'Acme Corp';

Eliminar registros

DELETE FROM analytics.dim_clientes
WHERE segmento = 'Inactivo';

#Funciones de fecha

Función Resultado
SELECT current_date Fecha actual (YYYY-MM-DD)
SELECT current_time Hora actual con timezone
SELECT NOW() Timestamp actual completo
SELECT age(ts1, ts2) Intervalo entre dos timestamps
SELECT make_date(2026,3,14) Construir fecha desde enteros
SELECT date_trunc('month', NOW()) Truncar a inicio de mes
SELECT EXTRACT(YEAR FROM NOW()) Extraer parte de una fecha

#Import/Export CSV

Exportar tabla a CSV

\copy analytics.dim_clientes TO '/tmp/clientes.csv' CSV HEADER
\copy (SELECT * FROM analytics.fact_ventas WHERE fecha > '2026-01-01') TO '/tmp/ventas_2026.csv' CSV HEADER

Importar CSV a tabla

\copy analytics.dim_clientes(nombre, segmento) FROM '/tmp/clientes_nuevos.csv' CSV HEADER

#Administración

#Usuarios y roles

Listar roles

SELECT rolname FROM pg_roles;

Crear usuario

CREATE USER analista WITH PASSWORD 'secure_password';

Eliminar usuario

DROP USER IF EXISTS analista;

Cambiar contraseña

ALTER ROLE analista WITH PASSWORD 'new_password';

Ver usuario actual

SELECT current_user;

#Permisos

Permisos completos en base de datos

GRANT ALL PRIVILEGES ON DATABASE analytics_db TO db_admin;

Permisos de lectura para analistas

GRANT CONNECT ON DATABASE analytics_db TO analista;
GRANT USAGE ON SCHEMA analytics TO analista;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics TO analista;

Permisos de escritura para pipelines

GRANT USAGE ON SCHEMA analytics TO pipeline_user;
GRANT SELECT, INSERT, UPDATE, DELETE
  ON ALL TABLES IN SCHEMA analytics TO pipeline_user;

Permisos en funciones

GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA analytics TO analista;

Aplicar permisos a tablas futuras

ALTER DEFAULT PRIVILEGES IN SCHEMA analytics
GRANT SELECT ON TABLES TO analista;

#Backup

Backup completo de todas las bases

$ pg_dumpall -U postgres > /backups/all_databases.sql

Backup de una base específica

$ pg_dump -U postgres -d analytics_db -f /backups/analytics_db.sql

Opciones frecuentes de pg_dump

Opción Descripción
-a Solo datos, sin esquema
-s Solo esquema, sin datos
-c Incluir DROP antes de CREATE
-C Incluir CREATE DATABASE
-t <tabla> Solo tabla(s) específica(s)
-F c Formato custom (comprimido)
-F d Formato directorio
-F t Formato tar

#Restore

Restaurar con psql (formato plain)

$ psql -U postgres analytics_db < /backups/analytics_db.sql

Restaurar con pg_restore (formato custom/tar)

$ pg_restore -U postgres -d analytics_db -c /backups/analytics_db.dump

Opciones frecuentes de pg_restore

Opción Descripción
-c Eliminar objetos antes de recrear
-C Crear base antes de restaurar
-e Salir si hay error
-j N Restaurar en N hilos paralelos
-t <tabla> Restaurar solo tabla específica

#Acceso remoto

Localizar archivo de configuración

$ psql -U postgres -c 'SHOW config_file'

Habilitar conexiones remotas en postgresql.conf

listen_addresses = '*'

Agregar reglas en pg_hba.conf

# Acceso desde red interna (ajustar CIDR a tu red)
host  all  all  <tu-red-cidr>  md5

Reiniciar servicio

$ sudo systemctl restart postgresql

#Monitoreo y diagnóstico

Conexiones activas

SELECT pid, usename, datname, state, query
FROM pg_stat_activity
WHERE state = 'active';

Tamaño de bases de datos

SELECT datname, pg_size_pretty(pg_database_size(datname))
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

Tamaño de tablas en un esquema

SELECT tablename,
       pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename))
FROM pg_tables
WHERE schemaname = 'analytics'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

Queries lentas (requiere pg_stat_statements)

SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

#Instancias

#Bases de datos del stack

Base de datos Servicio Propósito
airflow_db Apache Airflow Metadatos de DAGs, runs y tareas
superset_db Apache Superset Dashboards, datasets, permisos
openmetadata_db OpenMetadata Catálogo de datos y linaje
analytics_db Datos analíticos Tablas dimensionales y de hechos

#Convenciones de esquemas

Cada servicio debe usar su propio esquema, nunca public

-- Verificar esquemas existentes
SELECT schema_name FROM information_schema.schemata
WHERE schema_name NOT IN ('pg_catalog', 'information_schema');

Patrón de naming

Tipo Convención Ejemplo
Esquema <servicio>_<contexto> airflow_metadata
Tabla dimensión dim_<entidad> dim_clientes
Tabla de hechos fact_<proceso> fact_ventas
Tabla staging stg_<fuente>_<entidad> stg_crm_contactos
Vista vw_<descripción> vw_resumen_mensual

#Verificación rápida del stack

Verificar que todas las bases existen

$ psql -U postgres -c "\l" | grep -E "airflow|superset|openmetadata|analytics"

Verificar conexión a una base específica

$ psql -U postgres -d airflow_db -c "SELECT 1 AS test;"

Contar tablas por esquema

SELECT schemaname, COUNT(*) AS tablas
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
GROUP BY schemaname
ORDER BY tablas DESC;

#Extensiones recomendadas

Extensión Propósito
pg_stat_statements Monitoreo de queries
uuid-ossp Generación de UUIDs
pgcrypto Funciones criptográficas
pg_trgm Búsqueda por similitud de texto
tablefunc Tablas cruzadas (crosstab)

Instalar extensión

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

#Also see