ALTER TABLE MODIFY COLUMN

La cláusula MODIFY COLUMN de ALTER TABLE cambia la definición de una columna existente sin renombrarla. Puedes cambiar su tipo de datos, añadir o quitar restricciones, modificar el valor por defecto o cambiar su posición en la tabla. Es la forma estándar de ajustar columnas cuando los requisitos cambian.

Sintaxis

ALTER TABLE nombre_tabla
    MODIFY COLUMN nombre_columna nueva_definicion [FIRST | AFTER columna];

Debes especificar la definición completa de la columna, no solo lo que cambia. Si una columna es VARCHAR(100) NOT NULL y quieres cambiarla a VARCHAR(200), pero olvidas el NOT NULL, la columna pasará a admitir nulos.

Tabla de ejemplo

CREATE TABLE articulos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    titulo VARCHAR(100) NOT NULL,
    contenido TEXT,
    visitas INT DEFAULT 0,
    estado VARCHAR(10) DEFAULT 'borrador',
    creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
 
INSERT INTO articulos (titulo, contenido, visitas, estado) VALUES
('Introducción a MySQL', 'MySQL es un sistema de gestión...', 150, 'publicado'),
('Consultas avanzadas', 'Las subconsultas permiten...', 89, 'publicado'),
('Optimización', NULL, 0, 'borrador');

Cambiar el tamaño de una columna

El caso más común es ampliar el tamaño de un VARCHAR:

ALTER TABLE articulos
    MODIFY COLUMN titulo VARCHAR(200) NOT NULL;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

Los datos existentes se mantienen intactos. Ampliar el tamaño de un VARCHAR es una operación segura: los valores actuales siempre caben en el nuevo tamaño.

Reducir el tamaño es diferente. Si algún valor existente excede el nuevo límite, MySQL trunca el dato o devuelve un error según el modo SQL activo:

-- Modo estricto (por defecto en MySQL 8.0): devuelve error
ALTER TABLE articulos
    MODIFY COLUMN titulo VARCHAR(10) NOT NULL;
ERROR 1265 (01000): Data truncated for column 'titulo' at row 1

Cambiar el tipo de datos

Puedes cambiar el tipo de una columna si los datos existentes son compatibles:

ALTER TABLE articulos
    MODIFY COLUMN visitas BIGINT DEFAULT 0;

Pasar de INT a BIGINT es seguro porque todos los valores INT caben en BIGINT. El cambio inverso también funciona si los valores no exceden el rango del tipo destino.

Para cambios más drásticos, como de numérico a texto:

ALTER TABLE articulos
    MODIFY COLUMN visitas VARCHAR(20) DEFAULT '0';

MySQL convierte automáticamente los números a sus representaciones en texto. La conversión inversa (de texto a número) solo funciona si todos los valores existentes son numéricos válidos.

Añadir NOT NULL

ALTER TABLE articulos
    MODIFY COLUMN contenido TEXT NOT NULL;
ERROR 1138 (22004): Invalid use of NULL value

La operación falla porque la fila 3 ('Optimización') tiene NULL en contenido. Primero debes actualizar los valores nulos:

UPDATE articulos SET contenido = '' WHERE contenido IS NULL;
 
ALTER TABLE articulos
    MODIFY COLUMN contenido TEXT NOT NULL;
Query OK, 0 rows affected (0.04 sec)

Ahora la columna no admite nulos. Cualquier intento de insertar o actualizar a NULL producirá un error.

Quitar NOT NULL

Para permitir valores nulos en una columna que antes no los admitía:

ALTER TABLE articulos
    MODIFY COLUMN contenido TEXT;

Al no incluir NOT NULL en la nueva definición, la columna pasa a admitir nulos. Los datos existentes no se modifican.

Cambiar el valor por defecto

ALTER TABLE articulos
    MODIFY COLUMN estado VARCHAR(20) NOT NULL DEFAULT 'borrador';

Cambiamos dos cosas: ampliamos de VARCHAR(10) a VARCHAR(20) y hacemos la columna NOT NULL. El valor por defecto sigue siendo 'borrador'. Los datos existentes no cambian, solo las nuevas inserciones se ven afectadas por el nuevo tamaño máximo y la obligatoriedad.

También puedes usar ALTER COLUMN solo para cambiar o eliminar el valor por defecto sin redefinir la columna completa:

-- Cambiar solo el default
ALTER TABLE articulos
    ALTER COLUMN estado SET DEFAULT 'pendiente';
 
-- Eliminar el default
ALTER TABLE articulos
    ALTER COLUMN visitas DROP DEFAULT;

ALTER COLUMN es más ligero que MODIFY COLUMN porque no requiere reconstruir la tabla.

Cambiar la posición de una columna

ALTER TABLE articulos
    MODIFY COLUMN estado VARCHAR(20) NOT NULL DEFAULT 'pendiente' AFTER titulo;

Mover una columna de posición no afecta a los datos ni al rendimiento. Es una operación de reorganización visual.

DESCRIBE articulos;
FieldTypeNullKeyDefaultExtra
idintNOPRINULLauto_increment
titulovarchar(200)NONULL
estadovarchar(20)NOpendiente
contenidotextYESNULL
visitasvarchar(20)YESNULL
creado_entimestampYESCURRENT_TIMESTAMPDEFAULT_GENERATED

Cambiar a ENUM

ALTER TABLE articulos
    MODIFY COLUMN estado ENUM('borrador', 'pendiente', 'publicado', 'archivado')
        NOT NULL DEFAULT 'borrador';

Los valores existentes deben coincidir con alguno de los valores del ENUM. Si alguna fila contiene un valor que no está en la lista, MySQL devuelve un error en modo estricto.

Modificar múltiples columnas

Puedes modificar varias columnas en una sola sentencia:

ALTER TABLE articulos
    MODIFY COLUMN titulo VARCHAR(250) NOT NULL,
    MODIFY COLUMN visitas INT UNSIGNED DEFAULT 0,
    MODIFY COLUMN creado_en DATETIME DEFAULT CURRENT_TIMESTAMP;

MySQL ejecuta todas las modificaciones en una sola pasada por la tabla.

MODIFY vs CHANGE

MODIFY cambia la definición sin renombrar. CHANGE permite renombrar y cambiar la definición al mismo tiempo:

-- Solo cambiar definición (MODIFY)
ALTER TABLE articulos
    MODIFY COLUMN titulo VARCHAR(250) NOT NULL;
 
-- Renombrar y cambiar definición (CHANGE)
ALTER TABLE articulos
    CHANGE COLUMN titulo encabezado VARCHAR(250) NOT NULL;

Usa MODIFY cuando solo necesitas ajustar el tipo o las restricciones. Usa CHANGE cuando necesitas renombrar la columna. Usa RENAME COLUMN cuando solo necesitas renombrar sin cambiar la definición (MySQL 8.0).

Precauciones

Antes de modificar columnas en tablas con datos, ten en cuenta estas consideraciones. Conversiones de tipo incompatibles pueden causar pérdida de datos: pasar de TEXT a VARCHAR(50) trunca textos largos. Añadir NOT NULL falla si hay valores nulos existentes. Reducir el tamaño de un VARCHAR falla si hay valores que exceden el nuevo límite. En tablas grandes, MODIFY COLUMN puede llevar varios minutos porque MySQL necesita reconstruir la tabla completa.

Como regla general, verifica los datos existentes antes de hacer modificaciones restrictivas:

-- Antes de reducir VARCHAR(200) a VARCHAR(100)
SELECT id, titulo, LENGTH(titulo) AS longitud
FROM articulos
WHERE LENGTH(titulo) > 100;
 
-- Antes de añadir NOT NULL
SELECT COUNT(*) AS nulos
FROM articulos
WHERE contenido IS NULL;

Limpieza

DROP TABLE IF EXISTS articulos;

En el siguiente artículo veremos cómo eliminar columnas con ALTER TABLE DROP COLUMN.

Escrito por Eduardo Lázaro