BLOB
Los tipos BLOB (Binary Large Object) almacenan datos binarios sin interpretar: imágenes, PDFs, archivos comprimidos, datos serializados o cualquier secuencia de bytes. A diferencia de TEXT, BLOB no tiene conjunto de caracteres ni collation. Las comparaciones y ordenamientos se hacen byte a byte.
Los cuatro tipos BLOB
| Tipo | Tamaño máximo | Bytes |
|---|---|---|
| TINYBLOB | 255 bytes | L + 1 |
| BLOB | 65,535 bytes (~64 KB) | L + 2 |
| MEDIUMBLOB | 16,777,215 bytes (~16 MB) | L + 3 |
| LONGBLOB | 4,294,967,295 bytes (~4 GB) | L + 4 |
L es la longitud real de los datos. El prefijo (1-4 bytes) almacena la longitud.
Ejemplo básico
CREATE TABLE archivos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(255) NOT NULL,
tipo_mime VARCHAR(100) NOT NULL,
tamano INT UNSIGNED NOT NULL,
contenido MEDIUMBLOB NOT NULL,
subido_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insertar datos binarios desde un archivo (desde el cliente MySQL)
-- LOAD_FILE lee un archivo del sistema de archivos del servidor
INSERT INTO archivos (nombre, tipo_mime, tamano, contenido)
VALUES ('logo.png', 'image/png', 4096, LOAD_FILE('/ruta/al/logo.png'));En la práctica, la inserción de datos binarios se hace desde una aplicación:
-- Desde una aplicación, se usaría un prepared statement
-- INSERT INTO archivos (nombre, tipo_mime, tamano, contenido) VALUES (?, ?, ?, ?)
-- Y se pasaría el contenido binario como parámetroBLOB vs TEXT
| Característica | BLOB | TEXT |
|---|---|---|
| Contenido | Datos binarios | Texto legible |
| Character set | Ninguno (bytes crudos) | utf8mb4, latin1, etc. |
| Collation | Ninguno (binario) | Según el character set |
| Comparaciones | Byte a byte (case-sensitive) | Según collation (normalmente case-insensitive) |
| DEFAULT | No soportado | No soportado |
| Índice | Solo prefijo | Solo prefijo |
Almacenar imágenes
CREATE TABLE avatares (
usuario_id INT PRIMARY KEY,
imagen BLOB NOT NULL,
formato ENUM('jpeg', 'png', 'webp') NOT NULL,
FOREIGN KEY (usuario_id) REFERENCES clientes(id)
);Aunque es posible almacenar imágenes en MySQL, en la mayoría de los casos es mejor almacenar el archivo en el sistema de archivos o en un servicio de almacenamiento (S3, Cloud Storage) y guardar solo la ruta en la base de datos:
-- Mejor enfoque: guardar la ruta, no el archivo
CREATE TABLE avatares_ref (
usuario_id INT PRIMARY KEY,
ruta_imagen VARCHAR(500) NOT NULL,
formato ENUM('jpeg', 'png', 'webp') NOT NULL,
FOREIGN KEY (usuario_id) REFERENCES clientes(id)
);Cuándo usar BLOB
Sí usar BLOB:
- Datos pequeños que necesitan integridad transaccional (firmas digitales, tokens encriptados)
- Prototipos rápidos donde la infraestructura de archivos no está lista
- Datos binarios que deben viajar con el backup de la base de datos
- Thumbnails o imágenes muy pequeñas (menos de 10 KB)
No usar BLOB:
- Imágenes, videos o archivos grandes (usar sistema de archivos o almacenamiento en la nube)
- Datos que necesitan ser servidos directamente por un servidor web
- Archivos que se acceden con frecuencia (cada lectura carga la base de datos)
Funciones con BLOB
-- LENGTH devuelve el tamaño en bytes
SELECT nombre, LENGTH(contenido) AS bytes FROM archivos;
-- HEX convierte a representación hexadecimal
SELECT HEX(contenido) AS hex_contenido FROM archivos LIMIT 1;
-- Crear datos binarios desde hexadecimal
SELECT UNHEX('48656C6C6F') AS binario;| binario |
|---|
| Hello |
Almacenar datos encriptados
Un caso de uso legítimo para BLOB es almacenar datos encriptados:
CREATE TABLE datos_sensibles (
id INT AUTO_INCREMENT PRIMARY KEY,
usuario_id INT NOT NULL,
dato_encriptado BLOB NOT NULL,
iv BINARY(16) NOT NULL,
creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- AES_ENCRYPT y AES_DECRYPT de MySQL
INSERT INTO datos_sensibles (usuario_id, dato_encriptado, iv)
VALUES (1, AES_ENCRYPT('datos secretos', 'clave_secreta'), RANDOM_BYTES(16));Limitaciones
Sin DEFAULT: Al igual que TEXT, las columnas BLOB no pueden tener un valor por defecto.
Índices de prefijo: Solo puedes indexar los primeros N bytes:
CREATE TABLE docs (
id INT PRIMARY KEY,
contenido BLOB,
INDEX idx_contenido (contenido(100))
);max_allowed_packet: El tamaño máximo de un paquete MySQL limita el tamaño del BLOB que puedes insertar. El valor por defecto es 64 MB:
SHOW VARIABLES LIKE 'max_allowed_packet';| Variable_name | Value |
|---|---|
| max_allowed_packet | 67108864 |
Para insertar BLOBs más grandes, necesitas aumentar este valor en la configuración del servidor.
Limpieza
DROP TABLE IF EXISTS archivos;
DROP TABLE IF EXISTS avatares;
DROP TABLE IF EXISTS avatares_ref;
DROP TABLE IF EXISTS datos_sensibles;
DROP TABLE IF EXISTS docs;En el siguiente artículo veremos VARBINARY y BINARY, los tipos binarios de longitud fija y variable para datos más pequeños.
Escrito por Eduardo Lázaro
