TEXT
Los tipos TEXT almacenan cadenas de texto largas. Mientras que VARCHAR tiene un límite práctico de ~16,000 caracteres (con utf8mb4), TEXT puede almacenar hasta 4 GB de texto. MySQL ofrece cuatro variantes de TEXT con diferentes capacidades máximas. Son ideales para descripciones, comentarios, artículos y cualquier texto de longitud impredecible.
Los cuatro tipos TEXT
| Tipo | Tamaño máximo | Bytes |
|---|---|---|
| TINYTEXT | 255 bytes | L + 1 |
| TEXT | 65,535 bytes (~64 KB) | L + 2 |
| MEDIUMTEXT | 16,777,215 bytes (~16 MB) | L + 3 |
| LONGTEXT | 4,294,967,295 bytes (~4 GB) | L + 4 |
L es la longitud real del texto almacenado. El prefijo (1-4 bytes) almacena la longitud.
Ejemplo básico
CREATE TABLE articulos (
id INT AUTO_INCREMENT PRIMARY KEY,
titulo VARCHAR(200) NOT NULL,
resumen TEXT,
contenido MEDIUMTEXT NOT NULL,
metadata LONGTEXT
);
INSERT INTO articulos (titulo, resumen, contenido) VALUES
('Introducción a SQL', 'Una guía rápida sobre SQL básico', 'SQL es un lenguaje estándar para gestionar bases de datos relacionales...'),
('Guía de MySQL 8.0', 'Novedades de MySQL 8.0', 'MySQL 8.0 introdujo mejoras significativas en rendimiento y funcionalidad...');
SELECT id, titulo, LENGTH(contenido) AS bytes_contenido FROM articulos;| id | titulo | bytes_contenido |
|---|---|---|
| 1 | Introducción a SQL | 74 |
| 2 | Guía de MySQL 8.0 | 77 |
TEXT en tienda_mysql
Nuestra base de datos usa TEXT en varias tablas:
SELECT TABLE_NAME AS tabla, COLUMN_NAME AS columna, DATA_TYPE AS tipo
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'tienda_mysql'
AND DATA_TYPE = 'text'
ORDER BY TABLE_NAME;| tabla | columna | tipo |
|---|---|---|
| categorias | descripcion | text |
| pedidos | notas | text |
| productos | descripcion | text |
| resenas | comentario | text |
Veamos ejemplos reales:
SELECT nombre, LEFT(descripcion, 50) AS descripcion_corta
FROM productos
WHERE descripcion IS NOT NULL
LIMIT 5;| nombre | descripcion_corta |
|---|---|
| iPhone 15 Pro | Smartphone Apple con chip A17 Pro y cámara de 48M |
| Samsung Galaxy S24 | Smartphone Samsung con Galaxy AI y pantalla AMOLE |
| Google Pixel 8 | Smartphone Google con procesador Tensor G3 |
| Xiaomi 14 | Smartphone Xiaomi con cámara Leica |
| MacBook Air M3 | Portátil Apple ultraligero con chip M3 |
LEFT(texto, n) extrae los primeros n caracteres. Es útil para mostrar previsualizaciones de campos TEXT largos.
TEXT vs VARCHAR
| Característica | VARCHAR(n) | TEXT |
|---|---|---|
| Longitud máxima | 65,535 bytes (compartido con la fila) | 65,535 bytes (independiente) |
| DEFAULT | Soporta valores por defecto | No soporta DEFAULT |
| Índice | Completo | Solo con prefijo |
| Almacenamiento | En la fila (inline) | Puntero en la fila, datos fuera |
| Ordenamiento | Sobre el valor completo | Sobre los primeros max_sort_length bytes |
La diferencia clave de almacenamiento: VARCHAR se almacena directamente en la fila de la tabla. TEXT almacena un puntero en la fila y los datos reales en un área separada (overflow pages en InnoDB). Esto hace que las consultas que no usan la columna TEXT sean más rápidas, porque MySQL no necesita leer los datos de texto.
No soporta DEFAULT
-- Esto da error:
CREATE TABLE test_default (
contenido TEXT DEFAULT 'valor'
);ERROR 1101 (42000): BLOB, TEXT, GEOMETRY or JSON column 'contenido' can't have a default value
Para simular un default, usa un trigger o establece el valor en la lógica de la aplicación.
Indexar columnas TEXT
No puedes crear un índice completo sobre una columna TEXT. Necesitas un índice de prefijo:
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
contenido TEXT NOT NULL,
INDEX idx_contenido (contenido(100)) -- Indexa los primeros 100 caracteres
);El número entre paréntesis indica cuántos caracteres se indexan. Un prefijo más largo da búsquedas más precisas pero ocupa más espacio en el índice.
Para búsquedas de texto completo, usa un índice FULLTEXT en lugar de un índice de prefijo:
ALTER TABLE posts ADD FULLTEXT INDEX ft_contenido (contenido);
SELECT * FROM posts WHERE MATCH(contenido) AGAINST('mysql' IN NATURAL LANGUAGE MODE);Funciones útiles con TEXT
-- Longitud
SELECT
comentario,
CHAR_LENGTH(comentario) AS caracteres,
LENGTH(comentario) AS bytes
FROM resenas
LIMIT 3;| comentario | caracteres | bytes |
|---|---|---|
| Excelente teléfono, la cámara es espectacular | 47 | 48 |
| Muy buen móvil, pero la batería podría durar más | 51 | 54 |
| Gran rendimiento, aunque es caro | 32 | 32 |
-- Buscar dentro del texto
SELECT nombre, comentario
FROM resenas r
JOIN productos p ON r.producto_id = p.id
WHERE comentario LIKE '%cámara%';| nombre | comentario |
|---|---|
| iPhone 15 Pro | Excelente teléfono, la cámara es espectacular |
TINYTEXT, MEDIUMTEXT y LONGTEXT
TINYTEXT (255 bytes): Rara vez se usa. VARCHAR(255) es mejor porque soporta índices completos y valores por defecto.
MEDIUMTEXT (16 MB): Ideal para artículos largos, documentos, contenido HTML extenso.
LONGTEXT (4 GB): Para contenido muy grande como libros completos o logs extensos. Rara vez necesario.
CREATE TABLE documentos (
id INT AUTO_INCREMENT PRIMARY KEY,
titulo VARCHAR(200) NOT NULL,
resumen TINYTEXT, -- Hasta 255 bytes
contenido TEXT, -- Hasta 64 KB
manual MEDIUMTEXT, -- Hasta 16 MB
archivo_completo LONGTEXT -- Hasta 4 GB
);En la práctica, TEXT (64 KB) cubre la mayoría de los casos. MEDIUMTEXT se usa para CMS o aplicaciones con contenido editorial extenso.
Truncamiento en ordenamiento
MySQL solo usa los primeros max_sort_length bytes (por defecto 1024) al ordenar columnas TEXT:
SHOW VARIABLES LIKE 'max_sort_length';| Variable_name | Value |
|---|---|
| max_sort_length | 1024 |
Si tienes textos que difieren después de los primeros 1024 bytes y necesitas ordenarlos correctamente, puedes aumentar este valor para tu sesión:
SET SESSION max_sort_length = 4096;Buenas prácticas
Usa VARCHAR cuando la longitud máxima es predecible y menor a ~1000 caracteres. Usa TEXT cuando la longitud es impredecible o potencialmente larga.
Evita seleccionar columnas TEXT cuando no las necesitas:
-- Malo: trae todos los datos TEXT aunque no los uses
SELECT * FROM productos;
-- Mejor: selecciona solo las columnas necesarias
SELECT id, nombre, precio FROM productos;Esto es importante porque los datos TEXT se almacenan fuera de la fila principal y leerlos requiere acceso adicional a disco.
Limpieza
DROP TABLE IF EXISTS articulos;
DROP TABLE IF EXISTS posts;
DROP TABLE IF EXISTS documentos;En el siguiente artículo veremos ENUM, el tipo para columnas que solo pueden contener un valor de una lista predefinida.
Escrito por Eduardo Lázaro
