DataSkills Hub

MySQL

MySQL es una base de datos relacional ampliamente utilizada para aplicaciones web y sistemas transaccionales. Los datos se pueden consultar también vía Trino para análisis cross-database.

#Getting Started

#Conectarse a MySQL

Conexión local

$ mysql -u root -p

Conexión remota con host y puerto

$ mysql -h <host> -P <port> -u <user> -p

Conexión directa a una base de datos

$ mysql -h <host> -u <user> -p <database>

#Operaciones con Bases de Datos

Comando Descripción
CREATE DATABASE <db>; Crear base de datos
SHOW DATABASES; Listar bases de datos
USE <db>; Seleccionar base de datos
DROP DATABASE <db>; Eliminar base de datos
SELECT DATABASE(); Ver base de datos actual
SHOW CREATE DATABASE <db>; Ver DDL de creación

#Operaciones con Tablas

Comando Descripción
SHOW TABLES; Listar tablas del DB actual
DESC <tabla>; Ver estructura de una tabla
SHOW FIELDS FROM <tabla>; Listar columnas de una tabla
SHOW CREATE TABLE <tabla>; Ver DDL de creación de tabla
TRUNCATE TABLE <tabla>; Vaciar tabla (sin rollback)
DROP TABLE <tabla>; Eliminar tabla
SHOW TABLE STATUS; Ver metadata de tablas

#Tipos de Datos Comunes

Tipo Descripción
INT Entero (4 bytes)
BIGINT Entero grande (8 bytes)
DECIMAL(p,s) Número exacto (precisión, escala)
VARCHAR(n) Texto variable hasta n caracteres
TEXT Texto largo
DATE Fecha (YYYY-MM-DD)
DATETIME Fecha y hora
TIMESTAMP Marca de tiempo UTC
BOOLEAN Verdadero/Falso (alias TINYINT(1))
JSON Documento JSON nativo

#Comandos del Cliente

#Atajos dentro del Cliente MySQL

Comando Descripción
\h o help Mostrar ayuda
\s o status Estado del servidor
\u <db> Cambiar base de datos
\c Cancelar consulta actual
\q o exit Salir del cliente
\G Mostrar resultado en vertical
\! cmd Ejecutar comando del sistema
\. <archivo> Ejecutar script SQL

#Importar y Exportar Datos

Importar un archivo SQL

$ mysql -u <user> -p <db> < dump.sql

Exportar (backup) una base de datos

$ mysqldump -u <user> -p <db> > backup.sql

Exportar solo estructura (sin datos)

$ mysqldump -u <user> -p --no-data <db> > schema.sql

Exportar tabla específica

$ mysqldump -u <user> -p <db> <tabla> > tabla_backup.sql

Exportar resultado a CSV

SELECT * FROM ventas
INTO OUTFILE '/tmp/ventas.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

#Ejecución desde la Línea de Comandos

Ejecutar query directa

$ mysql -u <user> -p -e "SELECT COUNT(*) FROM db.tabla;"

Ejecutar archivo SQL

$ mysql -u <user> -p <db> < script.sql

Ejecución con formato de tabla

$ mysql -u <user> -p -t -e "SHOW DATABASES;"

#Consultas SQL Esenciales

#SELECT y Filtros

-- Seleccionar columnas específicas
SELECT id, nombre, fecha_registro
FROM clientes
WHERE estado = 'activo'
ORDER BY fecha_registro DESC
LIMIT 100;

-- Filtros con operadores
SELECT * FROM transacciones
WHERE monto > 1000
  AND fecha BETWEEN '2026-01-01' AND '2026-03-14'
  AND tipo IN ('venta', 'recarga');

-- Búsqueda por patrón
SELECT * FROM productos
WHERE nombre LIKE '%internet%';

#Agregaciones

-- Conteo y agrupamiento
SELECT region, COUNT(*) AS total, SUM(monto) AS ingresos
FROM ventas
WHERE fecha >= '2026-01-01'
GROUP BY region
HAVING ingresos > 50000
ORDER BY ingresos DESC;

-- Funciones de agregación comunes
SELECT
  COUNT(*) AS registros,
  COUNT(DISTINCT cliente_id) AS clientes_unicos,
  AVG(monto) AS promedio,
  MIN(monto) AS minimo,
  MAX(monto) AS maximo
FROM transacciones;

#JOINs

-- INNER JOIN
SELECT c.nombre, t.monto, t.fecha
FROM clientes c
INNER JOIN transacciones t ON c.id = t.cliente_id
WHERE t.fecha >= '2026-01-01';

-- LEFT JOIN (incluye clientes sin transacciones)
SELECT c.nombre, COALESCE(SUM(t.monto), 0) AS total
FROM clientes c
LEFT JOIN transacciones t ON c.id = t.cliente_id
GROUP BY c.nombre;

-- JOIN múltiple
SELECT c.nombre, p.producto, t.monto
FROM transacciones t
JOIN clientes c ON t.cliente_id = c.id
JOIN productos p ON t.producto_id = p.id;

#Subqueries y CTEs

-- Subquery en WHERE
SELECT nombre FROM clientes
WHERE id IN (
  SELECT DISTINCT cliente_id
  FROM transacciones
  WHERE monto > 5000
);

-- CTE (Common Table Expression)
WITH ventas_mensuales AS (
  SELECT
    DATE_FORMAT(fecha, '%Y-%m') AS mes,
    SUM(monto) AS total
  FROM ventas
  GROUP BY DATE_FORMAT(fecha, '%Y-%m')
)
SELECT mes, total
FROM ventas_mensuales
WHERE total > 100000
ORDER BY mes;

#INSERT, UPDATE y DELETE

-- Insertar registros
INSERT INTO clientes (nombre, email, estado)
VALUES ('Juan Pérez', '[email protected]', 'activo');

-- Insert masivo
INSERT INTO logs (evento, fecha)
VALUES
  ('login', NOW()),
  ('logout', NOW()),
  ('error', NOW());

-- Actualizar registros
UPDATE clientes
SET estado = 'inactivo', fecha_baja = NOW()
WHERE ultima_actividad < '2025-01-01';

-- Eliminar registros
DELETE FROM logs
WHERE fecha < DATE_SUB(NOW(), INTERVAL 90 DAY);

#CREATE TABLE

CREATE TABLE transacciones (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  cliente_id INT NOT NULL,
  producto_id INT NOT NULL,
  monto DECIMAL(12,2) NOT NULL,
  fecha DATETIME DEFAULT CURRENT_TIMESTAMP,
  estado VARCHAR(20) DEFAULT 'pendiente',
  INDEX idx_cliente (cliente_id),
  INDEX idx_fecha (fecha),
  FOREIGN KEY (cliente_id) REFERENCES clientes(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

#Administración

#Gestión de Usuarios

-- Crear usuario
CREATE USER 'analista'@'%'
IDENTIFIED BY 'password_seguro';

-- Otorgar permisos de solo lectura
GRANT SELECT ON ventas_db.* TO 'analista'@'%';

-- Otorgar todos los permisos en una DB
GRANT ALL PRIVILEGES ON app_db.*
TO 'app_user'@'<host>';

-- Ver permisos de un usuario
SHOW GRANTS FOR 'analista'@'%';

-- Revocar permisos
REVOKE INSERT, UPDATE ON ventas_db.*
FROM 'analista'@'%';

-- Aplicar cambios de permisos
FLUSH PRIVILEGES;

#Monitoreo y Procesos

Comando Descripción
SHOW PROCESSLIST; Listar procesos activos
SHOW FULL PROCESSLIST; Procesos con query completa
KILL <pid>; Terminar un proceso
SHOW STATUS; Variables de estado del servidor
SHOW VARIABLES LIKE '%max%'; Buscar variables de configuración
SHOW ENGINE INNODB STATUS\G Estado detallado de InnoDB

#Índices

-- Crear índice
CREATE INDEX idx_fecha ON transacciones(fecha);

-- Crear índice compuesto
CREATE INDEX idx_cliente_fecha
ON transacciones(cliente_id, fecha);

-- Crear índice único
CREATE UNIQUE INDEX idx_email
ON clientes(email);

-- Ver índices de una tabla
SHOW INDEX FROM transacciones;

-- Eliminar índice
DROP INDEX idx_fecha ON transacciones;

-- Analizar uso de índices en una query
EXPLAIN SELECT * FROM transacciones
WHERE cliente_id = 123 AND fecha > '2026-01-01';

#Mantenimiento de Tablas

-- Verificar tabla
CHECK TABLE transacciones;

-- Reparar tabla (MyISAM)
REPAIR TABLE logs;

-- Optimizar tabla (recuperar espacio)
OPTIMIZE TABLE transacciones;

-- Analizar distribución de claves
ANALYZE TABLE transacciones;

-- Ver tamaño de tablas
SELECT
  table_name AS tabla,
  ROUND(data_length / 1024 / 1024, 2) AS data_mb,
  ROUND(index_length / 1024 / 1024, 2) AS index_mb,
  table_rows AS filas_aprox
FROM information_schema.tables
WHERE table_schema = 'mi_base'
ORDER BY data_length DESC;

#Contexto

#MySQL en la Arquitectura de Datos

MySQL forma parte del Storage Layer de un stack de datos moderno:

Componente Rol en el stack
MySQL Sistemas legacy, apps con compatibilidad
PostgreSQL Base principal para nuevos servicios
Trino Capa de consulta federada cross-database

Los datos almacenados en MySQL se pueden consultar directamente desde Trino sin necesidad de mover los datos a otro sistema.

#Consultar MySQL desde Trino

-- Desde Trino: listar schemas del catálogo MySQL
SHOW SCHEMAS FROM mysql_catalog;

-- Desde Trino: consultar tabla MySQL
SELECT * FROM mysql_catalog.ventas_db.transacciones
WHERE fecha >= DATE '2026-01-01'
LIMIT 100;

-- Desde Trino: JOIN cross-database (MySQL + PostgreSQL)
SELECT
  m.cliente_id,
  m.monto,
  p.segmento
FROM mysql_catalog.ventas_db.transacciones m
JOIN postgres_catalog.crm.clientes p
  ON m.cliente_id = p.id
WHERE m.fecha >= DATE '2026-01-01';

#Buenas Prácticas

Práctica Detalle
Charset utf8mb4 Siempre usar para soporte completo de Unicode
Engine InnoDB Por defecto para tablas transaccionales
Índices en columnas de JOIN y WHERE Mejora el rendimiento de queries frecuentes
Usuarios con mínimo privilegio Analistas solo SELECT, apps solo lo necesario
Consultas pesadas vía Trino Para análisis cross-database, no sobrecargar MySQL
Backups periódicos con mysqldump Programar export diario de bases críticas
EXPLAIN antes de producción Validar plan de ejecución en queries nuevas
Evitar SELECT * en tablas grandes Especificar columnas para reducir I/O

#Funciones de Fecha Útiles

-- Fecha y hora actual
SELECT NOW(), CURDATE(), CURTIME();

-- Extraer partes de fecha
SELECT
  YEAR(fecha) AS anio,
  MONTH(fecha) AS mes,
  DAY(fecha) AS dia,
  DAYNAME(fecha) AS nombre_dia
FROM transacciones;

-- Aritmética de fechas
SELECT DATE_ADD(NOW(), INTERVAL 30 DAY);
SELECT DATE_SUB(NOW(), INTERVAL 7 DAY);
SELECT DATEDIFF('2026-03-14', '2026-01-01') AS dias;

-- Formatear fechas
SELECT DATE_FORMAT(NOW(), '%d/%m/%Y %H:%i') AS fecha_formateada;