En el desarrollo de software, una estructura de directorios común incluye carpetas como conf para configuración, core para lógica principal, lib para utilidades, log para registros, bin para ejecutables, db para datos generados y un archivo readme.md. Cuando un juego individual se transforma en multijugador en red, se necesita un servidor que almacene los datos compartidos: la base de datos. Este servidor atiende múltiples clientes que envían peticiones. MySQL es una aplicación basada en red que utiliza sockets. Soporta múltiples lenguajes como clientes gracias al lenguaje común SQL.
- Instalación de MySQL
Descargue la versión Community Server desde el sitio oficial. Se recomienda estabilidad sobre novedad, por ejemplo versiones 5.6 o 5.7. Tras descomprimir, mueva la carpeta a /usr/local (en macOS/Linux) con permisos de superusuario. En bin están los ejecutables principales: mysql (cliente) y mysqld (servidor). Para iniciar el servidor se usa mysql.server dentro de support-files.
- Conifguración en macOS
Las variables de entorno se definen en /etc/profile agregando:
export PATH=$PATH:/usr/local/mysql/bin:/usr/local/mysql/support-files
Para aplicar los cambios: source /etc/profile. Para que cargue automáticamente al abrir la terminal, añada esa línea al archivo ~/.zshrc. Luego inicialice la base de datos:
sudo mysqld --initialize --user=mysql
Esto genera un directorio data y muestra una contraseña temporal para root@localhost. Inicie el servicio con:
sudo mysql.server start
Conéctese:
mysql -u root -p
Cambie la contraseña:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'clave_segura';
- Recuperación de contraseña olvidada
Detenga el servidor: sudo mysql.server stop. Inicie sin verificación de permisos:
sudo mysqld_safe --skip-grant-tables
En otra terminal, acceda sin contraseña:
mysql -u root
Actualice la tabla de usuarios:
UPDATE mysql.user SET authentication_string=PASSWORD('nueva_clave') WHERE User='root' AND Host='localhost';
FLUSH PRIVILEGES;
Mate el proceso mysqld_safe (con sudo kill) e inicie el servicio normalmente.
- Configuración en Windows
Descargue el archivo comprimido y descomprímalo en una ruta sin espacios ni caracteres especiales. Agregue la carpeta bin al PATH del sistema. En una terminal como administrador, inicialice:
mysqld --initialize-insecure --user=mysql
Inicie el servidor con mysqld. Conéctese con mysql -u root (sin contraseña). Establezca una contraseña:
mysqladmin -u root password "clave123"
Para instalar MySQL como servicio de Windows:
mysqld -install
net start mysql
El servicio se configurará como inicio automático. Para eliminar: mysqld -remove.
- Codificación de caracteres
Para evitar problemas con caracteres especiales, se unifica a UTF-8. En macOS/Linux, edite /etc/my.cnf:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
En Windows, cree my.ini en el directorio raíz de MySQL con el mismo contenido. Reinicie el servicio y verifique con \s dentro del cliente MySQL.
- Bases de datos del sistema y comandos básicos
MySQL organiza los datos en bases de datos (carpetas) y tablas (archivos). Las bases de sistema incluyen:
information_schema(virtual, en memoria)mysql(tablas de usuarios y permisos)performance_schema(monitoreo)sys(vistas de diagnóstico)
El cliente MySQL admite atajos. Para no escribir usuario y contraseña cada vez, agregue en /etc/my.cnf bajo [mysql]:
user=root
password=clave_segura
- Operaciones con bases de datos
-- Crear (si no existe, con juego de caracteres)
CREATE DATABASE IF NOT EXISTS ventas DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- Eliminar
DROP DATABASE IF EXISTS ventas;
-- Modificar (cambiar solo el charset)
ALTER DATABASE ventas CHARACTER SET utf8mb4;
-- Mostrar todas
SHOW DATABASES;
-- Ver definición de una base
SHOW CREATE DATABASE ventas;
- Operaciones con tablas
Primero seleccione la base activa: USE ventas;. Para crear una tabla:
CREATE TABLE productos (
codigo INT,
nombre VARCHAR(100),
precio DECIMAL(8,2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Los motores de almacenamiento principales son:
- InnoDB: transaccional, crea archivos
.frm(estructura) e.ibd(datos). - MyISAM: rápido para lecturas, genera
.frm,.MYDy.MYI. - Memory: datos en RAM, solo
.frm. - Blackhole: no almacena datos.
Para modificar una tabla:
-- Agregar columna
ALTER TABLE productos ADD COLUMN stock INT NOT NULL DEFAULT 0;
-- Eliminar columna
ALTER TABLE productos DROP COLUMN stock;
-- Cambiar tipo de columna
ALTER TABLE productos MODIFY COLUMN nombre VARCHAR(200);
-- Renombrar columna y tipo
ALTER TABLE productos CHANGE COLUMN nombre descripcion TEXT;
-- Renombrar tabla
ALTER TABLE productos RENAME TO articulos;
Para copiar una tabla (estructura y datos) o solo la estructura:
CREATE TABLE productos_backup AS SELECT * FROM productos;
CREATE TABLE productos_estructura LIKE productos;
Eliminar tabla: DROP TABLE productos;
- Manipulación de registros (DML)
-- Insertar
INSERT INTO productos (codigo, nombre, precio) VALUES (1, 'Teclado', 45.50);
INSERT INTO productos VALUES (2, 'Ratón', 25.00), (3, 'Monitor', 320.75);
-- Actualizar
UPDATE productos SET precio = 49.99 WHERE codigo = 1;
-- Eliminar
DELETE FROM productos WHERE codigo = 3;
-- Eliminar todos los registros pero conservar la estructura
DELETE FROM productos;
-- Vaciar tabla y reiniciar autoincremento
TRUNCATE productos;
- Tipos de datos en MySQL
Numéricos enteros
TINYINT(1 byte),SMALLINT(2),MEDIUMINT(3),INT(4),BIGINT(8).- Se puede especificar
UNSIGNEDpara solo valores positivos. - El ancho en enteros solo afecta la visualización con
ZEROFILL.
Numéricos decimales
FLOAT(4 bytes),DOUBLE(8 bytes),DECIMAL(M,D)(precisión fija).
Cadenas
CHAR(N): longitud fija, rellena con espacios, hasta 255 caracteres.VARCHAR(N): longitud variable, hasta 65535 bytes (menos overhead).- La longitud máxima en caracteres depende del charset: con UTF-8 (3 bytes) el límite práctico es 21844 si es la única columna.
Fechas y horas
YEAR,DATE,TIME,DATETIME(8 bytes),TIMESTAMP(4 bytes, rango 1970-2038).
Enumeración y conjuntos
CREATE TABLE empleados (
id INT PRIMARY KEY,
nombre VARCHAR(50),
genero ENUM('M','F','O'),
habilidades SET('programar','diseñar','gestionar')
);
- Restricciones (constraints)
Valor por defecto y no nulo
CREATE TABLE clientes (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
email VARCHAR(100) NOT NULL,
pais VARCHAR(50) DEFAULT 'España',
PRIMARY KEY (id)
);
Unicidad
-- Unicidad simple (a nivel de columna)
CREATE TABLE usuarios (
id INT PRIMARY KEY,
username VARCHAR(30) UNIQUE
);
-- Unicidad compuesta
CREATE TABLE conexiones (
id INT,
ip VARCHAR(15),
puerto INT,
UNIQUE(ip, puerto)
);
Clave primaria
Toda tabla InnoDB necesita una clave primaria. Si no se define explícitamente, MySQL busca una columna UNIQUE NOT NULL o crea una interna oculta. Se recomienda usar id INT PRIMARY KEY AUTO_INCREMENT.
-- Clave primaria compuesta
CREATE TABLE logs (
usuario_id INT,
fecha DATETIME,
accion VARCHAR(50),
PRIMARY KEY (usuario_id, fecha)
);
Autoincremento
La columna debe ser parte de una clave (primaria o única). Se reinicia con TRUNCATE.
Clave foránea (FK)
Establece una relación entre tablas. Por ejemplo, una tabla pedidos referencia a clientes:
CREATE TABLE clientes (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100)
) ENGINE=InnoDB;
CREATE TABLE pedidos (
id INT PRIMARY KEY AUTO_INCREMENT,
fecha DATE,
cliente_id INT,
FOREIGN KEY (cliente_id) REFERENCES clientes(id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB;
Las acciones en cascada (CASCADE) propagan eliminaciones/actualizaciones. En proyectos grandes se prefiere manejar la integridad referencial en la aplicación y no usar FK físicas.
- Relaciones entre tablas
Uno a muchos (1:N)
Un cliante puede tener muchos pedidos. La FK se coloca en la tabla "muchos" (pedidos).
Muchos a muchos (M:N)
Por ejemplo, estudiantes y cursos:
CREATE TABLE estudiantes (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(60)
);
CREATE TABLE cursos (
id INT PRIMARY KEY AUTO_INCREMENT,
titulo VARCHAR(100)
);
CREATE TABLE inscripciones (
id INT PRIMARY KEY AUTO_INCREMENT,
estudiante_id INT,
curso_id INT,
FOREIGN KEY (estudiante_id) REFERENCES estudiantes(id)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (curso_id) REFERENCES cursos(id)
ON DELETE CASCADE ON UPDATE CASCADE
);
Uno a uno (1:1)
Extensión de una tabla, por ejemplo perfil de usuario. Se coloca una FK con UNIQUE en la tabla que representa la extensión.
- Consultas SELECT
Estructura general:
SELECT [DISTINCT] columnas
FROM tabla
[WHERE condiciones]
[GROUP BY columna]
[HAVING filtro_agregado]
[ORDER BY columna [ASC|DESC]]
[LIMIT inicio, cantidad];
Proyección y alias
SELECT nombre, precio * 1.21 AS precio_con_iva FROM productos;
Funciones de formato
SELECT CONCAT(nombre, ' - ', precio) AS descripcion FROM productos;
SELECT CONCAT_WS(' | ', id, nombre, precio) FROM productos;
Filtros WHERE
Operadores: =, <>, <, >, <=, >=. Combinación con AND, OR, NOT. Rangos: BETWEEN x AND y. Lista: IN (v1, v2, ...). Nulos: IS NULL / IS NOT NULL. Patrones: LIKE '_o%' ( _ un carácter, % cualquier secuencia). Expresiones regulares: WHERE nombre REGEXP '^[A-C].*'.
Agrupamiento y funciones de agregación
COUNT, SUM, AVG, MAX, MIN. Tras GROUP BY, en SELECT solo se pueden incluir columnas agrupadas o funciones de agregación.
SELECT departamento, COUNT(*) AS empleados, AVG(salario) AS salario_medio
FROM empleados
GROUP BY departamento
HAVING empleados > 3
ORDER BY salario_medio DESC;
La cláusula HAVING filtra después de agrupar (puede usar alias de agregación).
Ordenación y límite
SELECT * FROM productos ORDER BY precio DESC LIMIT 5;
-- Paginación: LIMIT offset, cantidad
SELECT * FROM productos LIMIT 0, 10; -- primeros 10
SELECT * FROM productos LIMIT 10, 10; -- del 11 al 20
- Ejemplo completo
Creación y consulta de una base de datos de una librería:
CREATE DATABASE libreria CHARACTER SET utf8mb4;
USE libreria;
CREATE TABLE autores (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(80) NOT NULL
);
CREATE TABLE libros (
id INT PRIMARY KEY AUTO_INCREMENT,
titulo VARCHAR(150) NOT NULL,
precio DECIMAL(7,2),
autor_id INT,
FOREIGN KEY (autor_id) REFERENCES autores(id)
ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO autores (nombre) VALUES ('Gabriel García Márquez'), ('Isabel Allende');
INSERT INTO libros (titulo, precio, autor_id) VALUES
('Cien años de soledad', 22.50, 1),
('La casa de los espíritus', 18.90, 2),
('El amor en los tiempos del cólera', 21.00, 1);
-- Libros con su autor
SELECT l.titulo, a.nombre AS autor, l.precio
FROM libros l
JOIN autores a ON l.autor_id = a.id
ORDER BY l.precio DESC;
Con esta base, se pueden realizar todas las operaciones vistas: inserción, actualización, eliminación y consultas complejas.