ALTER TABLE
La sentencia ALTER TABLE modifica la estructura de una tabla existente. Permite añadir, modificar o eliminar columnas, crear o eliminar índices y restricciones, renombrar la tabla, y cambiar sus opciones. Es la herramienta fundamental para evolucionar el esquema de la base de datos sin tener que recrear las tablas desde cero.
Sintaxis general
ALTER TABLE nombre_tabla
accion1,
accion2,
...;Puedes combinar múltiples acciones en una sola sentencia ALTER TABLE, separándolas por comas. MySQL las ejecuta todas en una única operación, lo que es más eficiente que ejecutar varias sentencias separadas.
Tabla de ejemplo
Para los ejemplos de este artículo, creamos una tabla de prueba:
CREATE TABLE empleados_demo (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL,
email VARCHAR(100),
salario DECIMAL(8, 2)
);
INSERT INTO empleados_demo (nombre, email, salario) VALUES
('Ana', 'ana@empresa.com', 35000.00),
('Luis', 'luis@empresa.com', 42000.00),
('Eva', 'eva@empresa.com', 38000.00);Añadir una columna
ALTER TABLE empleados_demo
ADD COLUMN departamento VARCHAR(50) DEFAULT 'General';Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
La nueva columna se añade al final de la tabla. Todas las filas existentes reciben el valor por defecto ('General' en este caso, o NULL si no se especifica valor por defecto).
Para verificar:
SELECT * FROM empleados_demo;| id | nombre | salario | departamento | |
|---|---|---|---|---|
| 1 | Ana | ana@empresa.com | 35000.00 | General |
| 2 | Luis | luis@empresa.com | 42000.00 | General |
| 3 | Eva | eva@empresa.com | 38000.00 | General |
Controlar la posición de la columna
Por defecto, la columna se añade al final. Puedes controlar su posición con FIRST o AFTER:
-- Al principio de la tabla
ALTER TABLE empleados_demo
ADD COLUMN codigo CHAR(5) FIRST;
-- Después de una columna específica
ALTER TABLE empleados_demo
ADD COLUMN telefono VARCHAR(20) AFTER email;Ahora la tabla tiene esta estructura:
DESCRIBE empleados_demo;| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| codigo | char(5) | YES | NULL | ||
| id | int | NO | PRI | NULL | auto_increment |
| nombre | varchar(50) | NO | NULL | ||
| varchar(100) | YES | NULL | |||
| telefono | varchar(20) | YES | NULL | ||
| salario | decimal(8,2) | YES | NULL | ||
| departamento | varchar(50) | YES | General |
Modificar una columna
Para cambiar el tipo de datos, las restricciones o el valor por defecto de una columna existente:
ALTER TABLE empleados_demo
MODIFY COLUMN email VARCHAR(150) NOT NULL;Esto cambia el tamaño máximo de email de 100 a 150 caracteres y la convierte en obligatoria. Los datos existentes se mantienen, siempre que sean compatibles con la nueva definición. Si alguna fila tiene NULL en email y la nueva definición es NOT NULL, la operación falla.
Cambiar el nombre de una columna
Para renombrar una columna y opcionalmente cambiar su tipo:
ALTER TABLE empleados_demo
CHANGE COLUMN salario sueldo DECIMAL(10, 2) NOT NULL;CHANGE requiere especificar tanto el nombre antiguo como el nuevo, además del tipo de datos completo. Si solo quieres cambiar el nombre sin modificar el tipo, debes repetir la definición del tipo.
MySQL 8.0 también permite renombrar sin redefinir el tipo:
ALTER TABLE empleados_demo
RENAME COLUMN sueldo TO salario;RENAME COLUMN solo cambia el nombre. Es más seguro porque no hay riesgo de modificar accidentalmente el tipo de datos.
Eliminar una columna
ALTER TABLE empleados_demo
DROP COLUMN codigo;La columna y todos sus datos se eliminan permanentemente. Si la columna tiene índices o es referenciada por una clave foránea, MySQL devuelve un error. Debes eliminar primero las dependencias.
Añadir una restricción
Puedes añadir restricciones a columnas existentes:
-- Añadir UNIQUE
ALTER TABLE empleados_demo
ADD CONSTRAINT uk_email UNIQUE (email);
-- Añadir CHECK
ALTER TABLE empleados_demo
ADD CONSTRAINT chk_salario CHECK (salario > 0);Dar nombre a las restricciones (como uk_email y chk_salario) facilita referenciarlas si necesitas eliminarlas o modificarlas después.
Eliminar una restricción
-- Eliminar UNIQUE
ALTER TABLE empleados_demo
DROP INDEX uk_email;
-- Eliminar CHECK
ALTER TABLE empleados_demo
DROP CHECK chk_salario;Las restricciones UNIQUE se eliminan con DROP INDEX porque MySQL las implementa internamente como índices. Las restricciones CHECK se eliminan con DROP CHECK.
Añadir y eliminar claves foráneas
-- Crear tabla referenciada
CREATE TABLE departamentos_demo (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL
);
-- Añadir clave foránea
ALTER TABLE empleados_demo
ADD COLUMN departamento_id INT,
ADD CONSTRAINT fk_departamento
FOREIGN KEY (departamento_id) REFERENCES departamentos_demo(id)
ON DELETE SET NULL;Para eliminar la clave foránea:
ALTER TABLE empleados_demo
DROP FOREIGN KEY fk_departamento;Eliminar la clave foránea no elimina la columna ni el índice asociado. Si también quieres eliminar el índice:
ALTER TABLE empleados_demo
DROP INDEX fk_departamento;Renombrar la tabla
ALTER TABLE empleados_demo
RENAME TO personal_demo;Esto cambia el nombre de la tabla. Las claves foráneas que referencian esta tabla se actualizan automáticamente.
Múltiples cambios en una sentencia
La ventaja principal de ALTER TABLE es que puedes combinar múltiples operaciones:
ALTER TABLE personal_demo
ADD COLUMN fecha_alta DATE,
MODIFY COLUMN nombre VARCHAR(100) NOT NULL,
DROP COLUMN telefono,
RENAME TO empleados_demo;MySQL ejecuta todas las operaciones en una sola pasada por la tabla, lo que es significativamente más rápido que ejecutar cuatro sentencias ALTER TABLE separadas, especialmente en tablas con muchos datos.
Cambiar opciones de tabla
ALTER TABLE empleados_demo
ENGINE = InnoDB,
DEFAULT CHARSET = utf8mb4,
COMMENT = 'Tabla de prueba para empleados';Cambiar el motor de almacenamiento reconstruye la tabla completa, lo que puede llevar tiempo en tablas grandes.
Consideraciones de rendimiento
En tablas con millones de filas, ALTER TABLE puede ser una operación costosa. Muchas operaciones requieren crear una copia de la tabla con la nueva estructura, copiar todos los datos, y reemplazar la tabla original. Durante este proceso, la tabla puede estar bloqueada para escrituras.
MySQL 8.0 soporta algunas operaciones "en línea" que no bloquean la tabla:
ALTER TABLE empleados_demo
ADD COLUMN nota TEXT,
ALGORITHM=INPLACE,
LOCK=NONE;ALGORITHM=INPLACE indica que MySQL no debe copiar la tabla. LOCK=NONE indica que no debe bloquear las lecturas ni escrituras. Si la operación no soporta estos modos, MySQL devuelve un error en lugar de degradar silenciosamente.
No todas las operaciones soportan INPLACE. Añadir una columna al final generalmente sí, pero cambiar el tipo de datos de una columna normalmente no.
Limpieza
DROP TABLE IF EXISTS empleados_demo;
DROP TABLE IF EXISTS departamentos_demo;En los siguientes artículos exploraremos en detalle las operaciones individuales de ALTER TABLE: añadir columnas, modificar columnas y eliminar columnas.
Escrito por Eduardo Lázaro
