CSV

El motor de almacenamiento CSV es uno de los más peculiares de MySQL. En lugar de utilizar un formato binario propietario para almacenar los datos, escribe cada fila como una línea de texto en un archivo CSV estándar, con los valores separados por comas y encerrados entre comillas. Este archivo puede abrirse directamente con cualquier editor de texto, hoja de cálculo como Excel o LibreOffice Calc, o procesarse con herramientas de línea de comandos.

La utilidad principal del motor CSV radica en el intercambio de datos. Si necesitas que una tabla sea accesible tanto desde MySQL como desde herramientas externas que trabajan con archivos CSV, este motor elimina la necesidad de exportar e importar datos manualmente.

Sintaxis

Para crear una tabla con el motor CSV:

CREATE TABLE nombre_tabla (
    columna1 tipo_dato NOT NULL,
    columna2 tipo_dato NOT NULL
) ENGINE = CSV;

Es importante destacar que todas las columnas deben ser NOT NULL. El motor CSV no soporta valores nulos.

Comportamiento básico

Cuando creas una tabla CSV, MySQL genera tres archivos en el directorio de la base de datos. El archivo .frm contiene la definición de la estructura, el archivo .CSV almacena los datos en formato de texto plano y el archivo .CSM contiene metadatos sobre el estado de la tabla.

CREATE TABLE exportaciones_diarias (
    fecha DATE NOT NULL,
    producto VARCHAR(100) NOT NULL,
    cantidad INT NOT NULL,
    precio_unitario DECIMAL(10,2) NOT NULL,
    total DECIMAL(12,2) NOT NULL
) ENGINE = CSV;

Al insertar datos, MySQL los escribe directamente en formato CSV:

INSERT INTO exportaciones_diarias VALUES
    ('2024-09-01', 'Laptop Pro 15', 12, 1299.99, 15599.88),
    ('2024-09-01', 'Monitor UltraWide', 25, 549.00, 13725.00),
    ('2024-09-02', 'Teclado Mecánico', 80, 89.50, 7160.00);

El contenido del archivo exportaciones_diarias.CSV en disco es texto plano legible:

"2024-09-01","Laptop Pro 15","12","1299.99","15599.88"
"2024-09-01","Monitor UltraWide","25","549.00","13725.00"
"2024-09-02","Teclado Mecánico","80","89.50","7160.00"

Puedes abrir este archivo directamente con Excel, importarlo a otro sistema o procesarlo con scripts sin necesidad de ejecutar ningún comando de exportación desde MySQL.

Caso práctico: intercambio bidireccional con hojas de cálculo

Una de las aplicaciones más útiles del motor CSV es permitir que usuarios no técnicos modifiquen datos directamente desde una hoja de cálculo. Imagina que el equipo de marketing necesita actualizar una tabla de precios promocionales sin acceder a MySQL.

CREATE TABLE precios_promocionales (
    sku VARCHAR(20) NOT NULL,
    nombre_producto VARCHAR(150) NOT NULL,
    precio_normal DECIMAL(10,2) NOT NULL,
    precio_promocion DECIMAL(10,2) NOT NULL,
    fecha_inicio DATE NOT NULL,
    fecha_fin DATE NOT NULL
) ENGINE = CSV;
 
INSERT INTO precios_promocionales VALUES
    ('SKU-001', 'Auriculares Bluetooth', 79.99, 59.99, '2024-10-01', '2024-10-15'),
    ('SKU-002', 'Cargador Inalámbrico', 34.99, 24.99, '2024-10-01', '2024-10-15');

El equipo de marketing puede abrir el archivo .CSV con Excel, añadir nuevas filas o modificar precios y guardar el archivo. Después, desde MySQL solo necesitas ejecutar:

FLUSH TABLES;

Esto obliga a MySQL a releer el archivo del disco, incorporando los cambios realizados externamente. Ahora puedes consultar los datos actualizados:

SELECT nombre_producto, precio_normal, precio_promocion
FROM precios_promocionales;
nombre_productoprecio_normalprecio_promocion
Auriculares Bluetooth79.9959.99
Cargador Inalámbrico34.9924.99
Ratón Ergonómico45.0032.00

La tercera fila fue añadida por el equipo de marketing directamente en el archivo CSV.

Caso práctico: exportación continua para sistemas externos

Otra aplicación práctica es mantener una tabla que sirve como punto de exportación continua para otros sistemas. Si tienes un proceso ETL que necesita consumir datos de MySQL en formato CSV, en lugar de ejecutar SELECT INTO OUTFILE periódicamente, puedes usar una tabla CSV que siempre está disponible como archivo.

CREATE TABLE feed_inventario (
    producto_id INT NOT NULL,
    nombre VARCHAR(200) NOT NULL,
    stock_actual INT NOT NULL,
    ubicacion_almacen VARCHAR(50) NOT NULL,
    ultima_actualizacion DATETIME NOT NULL
) ENGINE = CSV;

Un proceso programado puede actualizar la tabla periódicamente:

TRUNCATE TABLE feed_inventario;
 
INSERT INTO feed_inventario
SELECT p.id, p.nombre, i.stock, i.ubicacion, NOW()
FROM productos p
JOIN inventario i ON p.id = i.producto_id
WHERE i.stock > 0;

El sistema externo simplemente lee el archivo feed_inventario.CSV del disco sin necesidad de conectarse a MySQL.

Limitaciones del motor CSV

El motor CSV tiene varias restricciones importantes que limitan su uso a escenarios específicos. La más significativa es que no soporta índices de ningún tipo. Cada consulta SELECT realiza un escaneo completo de la tabla, lo que hace que el rendimiento se degrade rápidamente con tablas grandes.

-- Esta consulta siempre escanea toda la tabla, sin importar el filtro
SELECT * FROM exportaciones_diarias WHERE fecha = '2024-09-01';

Tampoco soporta transacciones, claves foráneas, columnas AUTO_INCREMENT ni columnas que permitan valores NULL. Si intentas crear una columna sin la restricción NOT NULL, MySQL rechaza la creación:

CREATE TABLE intento_csv (
    id INT,  -- Sin NOT NULL
    nombre VARCHAR(50) NOT NULL
) ENGINE = CSV;
-- ERROR 1178 (42000): The storage engine for the table doesn't support nullable columns

El formato de texto plano también implica que el almacenamiento es menos eficiente que los formatos binarios. Los números se almacenan como cadenas de texto, ocupando más espacio del necesario. Una tabla con millones de filas puede ser significativamente más grande en formato CSV que su equivalente en InnoDB.

Advertencia: No uses el motor CSV para tablas con más de unos pocos miles de filas. La ausencia de índices hace que cualquier consulta sea un escaneo completo, y el rendimiento se deteriora linealmente con el tamaño de la tabla. Para conjuntos de datos grandes, es mejor usar InnoDB y exportar a CSV cuando sea necesario.

Consejo: Si editas un archivo CSV externamente, asegúrate de respetar el formato exacto que MySQL espera: cada valor entre comillas dobles, separados por comas, sin línea de encabezado. Un formato incorrecto puede corromper la tabla. Después de editar, ejecuta CHECK TABLE nombre_tabla para verificar la integridad.

En el siguiente artículo aprenderás sobre el motor MERGE, que permite combinar varias tablas MyISAM idénticas en una sola vista unificada.

Escrito por Eduardo Lázaro