¿Se utiliza MySQL en finanzas?

MySQL Avanzado: Manipula Datos e Importa CSV

Valoración: 4.81 (5039 votos)

En el mundo de la administración de bases de datos, ir más allá de las operaciones básicas de inserción, actualización y eliminación (CRUD) es fundamental para manejar escenarios complejos y grandes volúmenes de información. El concepto de "MySQL Avanzado", en este contexto, se centra en la manipulación eficiente de datos, la integración con fuentes externas como archivos CSV y el manejo cuidadoso de las relaciones entre tablas para mantener la integridad referencial. Este artículo explorará estas técnicas esenciales que todo administrador o desarrollador que trabaje con MySQL debería dominar.

Veremos cómo insertar datos provenientes de otras consultas o archivos, cómo actualizar y eliminar registros de forma segura y masiva, y cómo gestionar las dependencias entre tablas. El manejo de archivos CSV (Comma Separated Values) es particularmente importante, ya que son un formato plano, delimitado por comas, ampliamente utilizado para el intercambio de datos entre diferentes plataformas debido a su universalidad. Si necesitas mover datos hacia o desde una base de datos MySQL, los archivos CSV te permiten hacerlo sin preocuparte por problemas de compatibilidad.

¿Es MySQL bueno para el comercio electrónico?
Opciones de bases de datos populares para el comercio electrónico MySQL: MySQL es un sistema de gestión de bases de datos relacionales de código abierto ampliamente utilizado. Es conocido por su velocidad y escalabilidad, lo que lo convierte en una excelente opción para aplicaciones de comercio electrónico con una gran variedad de productos y clientes .
Índice de Contenido

Insertando Datos Usando Consultas

Para refrescar la memoria, recordemos la sintaxis básica de una sentencia INSERT:

INSERT INTO Cliente (nombre, apellido) VALUES (‘Juan', ‘Pérez');

Esta sentencia inserta un nuevo registro en la tabla Cliente. Asumimos que hay una columna de auto-incremento para el ID único del registro.

La sentencia anterior es una forma básica de insertar datos, pero MySQL te permite usar otras consultas, específicamente sentencias SELECT, para añadir nuevos registros a tus tablas. Esto es extremadamente útil cuando importas datos de una fuente externa. A menudo, primero creas una tabla temporal a partir de esta fuente externa y luego usas una sentencia SELECT para importar los datos filtrados o transformados a tus tablas de producción.

Consideremos un ejemplo: tu empresa adquiere datos de una base de datos MySQL externa. Esta base de datos externa tiene una tabla Cliente, pero su estructura no es idéntica a la tuya. Además, la información de dirección del cliente está en una segunda tabla en la base de datos externa. Quieres crear una tabla temporal que contenga el nombre, apellido y la dirección del cliente antes de importarlos a tu tabla de producción.

El siguiente código SQL muestra cómo crear una tabla temporal a partir de una consulta SELECT:

CREATE TABLE TempCliente AS SELECT nombre, apellido FROM ClienteExterno AS c WHERE c.fecha_creacion >= ‘2015-08-01';

En esta consulta, se crea una nueva tabla llamada TempCliente a partir de la tabla ClienteExterno. Solo se incluyen los clientes creados después de una fecha específica. Creamos esta tabla temporal para poder revisar, filtrar o transformar los datos antes de insertarlos en una tabla de producción.

Como mencionamos, la dirección del cliente se encuentra en una tabla separada. La consulta anterior solo obtiene el nombre y apellido. Necesitamos unir la tabla DireccionExterna para incluir la dirección en nuestra tabla temporal. Puedes incluir sentencias JOIN directamente en la consulta que crea la tabla:

CREATE TABLE TempCliente AS SELECT c.nombre, c.apellido, a.direccion FROM ClienteExterno AS c INNER JOIN DireccionExterna AS a ON c.cliente_id = a.cliente_id WHERE c.fecha_creacion >= ‘2015-08-01';

Aquí usamos un INNER JOIN. Esto significa que cualquier cliente sin una dirección registrada será excluido. Si queremos incluir *todos* los clientes de la tabla externa, incluso si no tienen dirección, debemos cambiar el INNER JOIN por un LEFT JOIN. Esto incluirá todos los clientes de ClienteExterno y usará el valor por defecto NULL para la dirección si no se encuentra una coincidencia:

CREATE TABLE TempCliente AS SELECT c.nombre, c.apellido, a.direccion FROM ClienteExterno AS c LEFT JOIN DireccionExterna AS a ON c.cliente_id = a.cliente_id WHERE c.fecha_creacion >= ‘2015-08-01';

Un detalle importante al ejecutar repeatedly CREATE TABLE es que, una vez que la tabla existe, la sentencia fallará a menos que la elimines primero. Si necesitas regenerar la tabla temporal, usa DROP TABLE TempCliente; antes de ejecutar CREATE TABLE de nuevo.

Una vez creada la tabla temporal y habiendo filtrado o transformado los datos según sea necesario, puedes importarlos a tu tabla de producción principal. La sintaxis para insertar registros desde una sentencia SELECT a una tabla existente es similar a la de crear una tabla, pero usando INSERT INTO en lugar de CREATE TABLE:

INSERT INTO Cliente (nombre, apellido, direccion) SELECT nombre, apellido, direccion FROM TempCliente;

Es crucial que el número y orden de las columnas en la sentencia SELECT coincidan exactamente con el número y orden de las columnas especificadas en la sentencia INSERT INTO. Si no coinciden, la inserción fallará o, peor aún, se insertarán datos incorrectos, comprometiendo la integridad y precisión de tus datos. Nota que no se usa la palabra clave VALUES cuando se inserta desde una SELECT. También puedes añadir una cláusula WHERE a la sentencia INSERT si necesitas filtrar aún más los datos de TempCliente antes de la inserción final.

Actualizando Tablas desde una Consulta SELECT

Además de insertar nuevos registros, a menudo necesitarás actualizar datos existentes utilizando información de una fuente externa. Supongamos que tu tabla de clientes tiene datos antiguos o incompletos, pero tienes una tabla externa (quizás generada a partir de logs o una exportación reciente) que contiene información más actualizada, incluyendo el ID del cliente (que sirve como enlace único). Necesitas actualizar tu tabla principal con esta nueva información.

Al igual que con las actualizaciones básicas, usar una sentencia UPDATE con datos externos requiere precaución extrema, especialmente con la cláusula WHERE, para evitar modificar registros incorrectos. Tienes dos opciones principales para realizar actualizaciones utilizando datos de una consulta SELECT: unir las tablas con JOIN o usar una subconsulta.

Veamos la opción que utiliza JOIN:

UPDATE Cliente AS c LEFT JOIN TempCliente AS tc ON c.cliente_id = tc.cliente_id SET c.nombre = tc.nombre, c.apellido = tc.apellido, c.direccion = tc.direccion WHERE c.cliente_id > 5;

En esta sentencia, unimos la tabla Cliente (c) con la tabla TempCliente (tc) basándonos en el cliente_id. La cláusula SET especifica qué columnas se actualizarán en la tabla Cliente usando los valores correspondientes de la tabla TempCliente. La cláusula WHERE es fundamental para limitar qué registros se actualizan en la tabla Cliente; sin ella, cualquier cliente en Cliente que tenga una coincidencia en TempCliente sería actualizado. Actualizar una tabla sin una cláusula WHERE adecuada es una práctica muy peligrosa en entornos de producción.

La segunda opción utiliza una subconsulta:

UPDATE Cliente SET nombre = (SELECT nombre FROM TempCliente WHERE TempCliente.cliente_id = Cliente.cliente_id);

En este enfoque, la subconsulta (SELECT nombre FROM TempCliente WHERE TempCliente.cliente_id = Cliente.cliente_id) se ejecuta para cada fila en la tabla Cliente que está siendo considerada para la actualización. Si la subconsulta encuentra una coincidencia en TempCliente basada en el cliente_id, devuelve el nombre correspondiente, que luego se usa para actualizar la columna nombre en la fila actual de Cliente. Este método puede ser menos eficiente en términos de rendimiento para grandes conjuntos de datos en comparación con el enfoque JOIN, pero es una alternativa válida.

Eliminando Datos con Restricciones (Claves Foráneas)

Al trabajar con bases de datos relacionales que usan el motor InnoDB, te encontrarás con las clave externa (foreign keys) y las restricciones asociadas. Intentar eliminar un registro de una tabla padre (por ejemplo, un cliente) que tiene registros relacionados en una tabla hija (por ejemplo, pedidos) normalmente generará un error. Esto ocurre porque la eliminación dejaría registros huérfanos en la tabla hija (pedidos sin un cliente asociado), rompiendo la integridad referencial.

A pesar de que eliminar datos a menudo se desaconseja (siendo preferible marcarlos como inactivos), hay situaciones donde es necesario, como eliminar registros duplicados importados accidentalmente. Tienes dos opciones principales para manejar eliminaciones cuando existen restricciones de clave foránea:

La primera opción es eliminar manualmente los registros de las tablas hijas antes de eliminar el registro padre. Siguiendo el ejemplo del cliente y pedido, primero ejecutarías una sentencia DELETE en la tabla Pedido para los pedidos asociados al cliente que quieres eliminar, y luego eliminarías el cliente de la tabla Cliente. Esto puede volverse tedioso rápidamente en bases de datos con muchas relaciones y tablas.

La segunda opción, más automatizada, es configurar la opción ON DELETE CASCADE cuando defines la clave foránea. Con esta opción, cuando eliminas un registro de la tabla padre, MySQL automáticamente elimina todos los registros relacionados en la tabla hija. En el ejemplo del cliente y pedido, eliminar un cliente con ON DELETE CASCADE configurado en la clave foránea de la tabla Pedido resultaría en la eliminación automática de todos los pedidos asociados a ese cliente, evitando registros huérfanos.

Si tus tablas ya existen, puedes añadir o modificar la clave foránea con la opción ON DELETE CASCADE usando ALTER TABLE:

ALTER TABLE Pedido ADD CONSTRAINT fk_pedido_cliente FOREIGN KEY (cliente_id) REFERENCES Cliente (cliente_id) ON DELETE CASCADE;

Esta sentencia añade una restricción de clave foránea llamada fk_pedido_cliente a la tabla Pedido en la columna cliente_id, referenciando la tabla Cliente en su columna cliente_id. La opción ON DELETE CASCADE es la que habilita la eliminación en cascada.

Si bien ON DELETE CASCADE simplifica la eliminación de registros relacionados, debes usarla con extrema precaución. Un error al eliminar un registro padre podría resultar en la pérdida masiva de datos en tablas hijas que no esperabas eliminar. Asegúrate de entender completamente las dependencias y el impacto antes de usar esta opción, especialmente en entornos de producción.

Importando Datos desde un Archivo CSV

Como mencionamos, los archivos CSV son un formato universalmente entendido y son una herramienta invaluable para el intercambio de datos. MySQL ofrece una forma nativa y eficiente de importar datos desde archivos CSV directamente a tus tablas utilizando la sentencia LOAD DATA INFILE.

Para que la importación sea exitosa, el archivo CSV debe estar correctamente formateado. Cualquier error en la estructura (delimitadores, comillas, saltos de línea) puede causar problemas, desde datos mal formados hasta errores de MySQL o datos ingresados en los campos incorrectos.

Considera un archivo CSV simple para importar datos de clientes:

cliente_id,nombre,apellido 5,"Jennifer","Smith" 6,"Paul","Smith" 7,"Andrew","Johnson"

Observa que cada campo está separado por una coma, y las cadenas de texto (strings) están encerradas entre comillas dobles. El uso de comillas es crucial, especialmente si tus datos pueden contener comas. Por ejemplo, si tuvieras un campo de dirección:

cliente_id,nombre,apellido,direccion 5,"Jennifer","Smith","111 Comman, Law Ave" 6,"Paul","Smith","Note Street" 7,"Andrew","Johnson","Uncommon Location"

En el primer registro, la dirección "111 Comman, Law Ave" contiene una coma. Si esa dirección no estuviera entrecomillada, MySQL interpretaría la coma como un separador de campo, causando un error o truncando los datos. Por eso, es una buena práctica encerrar los valores de tipo string entre comillas.

Aquí tienes la sentencia LOAD DATA INFILE para importar el archivo CSV de clientes:

LOAD DATA INFILE 'c:/clientes/clientes.csv' INTO TABLE Cliente FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;

Analicemos la sentencia:

  • LOAD DATA INFILE 'ruta/archivo.csv': Especifica la ruta completa al archivo CSV en el sistema de archivos del servidor MySQL o del cliente (dependiendo de la configuración).
  • INTO TABLE NombreTabla: Indica la tabla destino donde se insertarán los datos.
  • FIELDS TERMINATED BY ',': Define el carácter que separa los campos dentro de cada línea (en este caso, la coma).
  • ENCLOSED BY '"': Define el carácter que encierra los valores de los campos, especialmente strings (en este caso, las comillas dobles).
  • LINES TERMINATED BY '\n': Define el carácter o secuencia que marca el final de cada línea o registro. \n representa el salto de línea, común en sistemas Unix/Linux. En Windows, podría ser necesario usar '\r\n'.
  • IGNORE 1 ROWS: Omite un número específico de líneas al principio del archivo. Esto es útil para ignorar la fila de encabezado que a menudo tienen los archivos CSV.

En muchos casos, los nombres de las columnas en tu archivo CSV no coincidirán exactamente con los nombres de las columnas en tu tabla de MySQL. Por ejemplo, el CSV podría tener un encabezado "first name" (con espacio) mientras que tu tabla tiene "nombre" o "first_name" (sin espacio o con guion bajo). Para manejar esto, puedes especificar el orden de las columnas en el CSV y mapearlas a las columnas de la tabla usando la cláusula SET.

Supongamos que tu archivo CSV tiene el encabezado "nombre cliente" en lugar de "nombre":

cliente_id,nombre cliente,apellido,direccion 5,"Jennifer","Smith","111 Comman, Law Ave" 6,"Paul","Smith","Note Street" 7,"Andrew","Johnson","Uncommon Location"

Para importar esto a una tabla Cliente con columnas cliente_id, nombre, apellido, direccion, usarías:

LOAD DATA INFILE 'c:/clientes/clientes.csv' INTO TABLE Cliente FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS (cliente_id, @nombre_csv, apellido, direccion) SET nombre = @nombre_csv;

En esta sentencia, después de IGNORE 1 ROWS, listamos las columnas del CSV en el orden en que aparecen. Para la columna "nombre cliente" del CSV, usamos una variable de usuario @nombre_csv (cualquier nombre de variable precedido por @). La cláusula SET nombre = @nombre_csv; indica a MySQL que el valor leído de la columna CSV mapeada a @nombre_csv debe ser asignado a la columna nombre de la tabla Cliente. Si tienes múltiples columnas con nombres distintos, simplemente mapeas cada una a una variable de usuario y luego usas múltiples asignaciones en la cláusula SET.

Exportando Datos a un Archivo CSV

Así como necesitas importar datos, también es común la necesidad de exportarlos, ya sea para compartirlos con otros departamentos, clientes o para transferirlos a otra plataforma de base de datos (como Oracle o SQL Server). Dado que el formato CSV es universal, exportar datos a este formato es una tarea frecuente para los administradores de bases de datos. MySQL tiene un comando nativo para exportar datos de una consulta directamente a un archivo CSV.

Para exportar, utilizas una sentencia SELECT combinada con la cláusula INTO OUTFILE. La sintaxis es similar a la de importación en cuanto a la especificación del formato, pero la dirección del flujo de datos es opuesta.

SELECT cliente_id, nombre, apellido, direccion FROM Cliente WHERE fecha_creacion >= '2015-08-01' INTO OUTFILE 'C:/exportaciones/clientes_agosto2015.csv' FIELDS ENCLOSED BY '"' ESCAPED BY '"' LINES TERMINATED BY '\n';

Analicemos esta sentencia de exportación:

  • SELECT columnas FROM Tabla WHERE ...: Es la consulta estándar que recupera los datos que deseas exportar. Puedes usar cualquier tipo de SELECT, incluyendo JOINs, GROUP BY, etc.
  • INTO OUTFILE 'ruta/archivo.csv': Especifica la ruta completa y el nombre del archivo donde se guardarán los datos exportados. La ruta debe ser accesible y escribible por el usuario con el que se ejecuta el servidor MySQL.
  • FIELDS ENCLOSED BY '"': Define el carácter que se usará para encerrar los campos en el archivo de salida (aquí, comillas dobles).
  • ESCAPED BY '"': Define el carácter utilizado para escapar caracteres especiales, como el propio carácter de encerramiento o el carácter de delimitación. Usar el mismo carácter que ENCLOSED BY es común.
  • LINES TERMINATED BY '\n': Define el carácter o secuencia que marcará el final de cada línea/registro en el archivo de salida. Aquí usamos el salto de línea estándar de Unix/Linux. Si el archivo se va a usar en Windows, '\r\n' podría ser más apropiado.

Después de ejecutar esta sentencia, se creará el archivo especificado con los datos de la consulta SELECT, formateados según las cláusulas FIELDS y LINES. Por ejemplo, el contenido del archivo podría verse así:

"5","Jennifer","Smith","111 Comman, Law Ave" "6","Paul","Smith","Note Street" "7","Andrew","Johnson","Uncommon Location"

(Nota que no hay fila de encabezado por defecto, a menos que la incluyas en la SELECT como una fila UNIONed). La elección del terminador de línea (LINES TERMINATED BY) es importante para la compatibilidad entre sistemas operativos. Usar '\n' o '\r\n' hace que el archivo sea más fácil de leer con editores de texto estándar, a diferencia del ejemplo de la fuente que usaba punto y coma, lo cual podría ser menos legible pero útil en algunos escenarios de importación/exportación entre bases de datos.

Preguntas Frecuentes (FAQ)

Aquí respondemos algunas preguntas comunes relacionadas con estos temas avanzados:

¿Es seguro usar ON DELETE CASCADE?

Es muy eficiente para mantener la integridad referencial automáticamente, pero también es potencialmente peligroso. Un error en una sentencia DELETE en la tabla padre puede borrar grandes cantidades de datos relacionados sin confirmación explícita. Úsalo con extrema precaución y asegúrate de tener copias de seguridad.

¿Qué hago si LOAD DATA INFILE da errores?

Los errores suelen deberse a un formato incorrecto en el archivo CSV. Verifica los delimitadores de campo (FIELDS TERMINATED BY), los caracteres de encerramiento (ENCLOSED BY) y los terminadores de línea (LINES TERMINATED BY). Asegúrate de que los datos no contengan caracteres especiales que no estén correctamente escapados o encerrados. También verifica los permisos de archivo y la ruta especificada.

¿Cuál es la mejor forma de actualizar datos masivamente, con JOIN o Subconsulta?

Generalmente, el enfoque usando JOIN (UPDATE ... JOIN ... SET) es más eficiente en MySQL para actualizaciones masivas, ya que el optimizador puede manejar mejor la operación. El enfoque con subconsulta puede ser menos eficiente porque la subconsulta puede ser ejecutada múltiples veces. Sin embargo, la elección puede depender del caso de uso específico y de la complejidad de la lógica de actualización.

¿LOAD DATA INFILE es más rápido que INSERT?

Sí, LOAD DATA INFILE es significativamente más rápido que ejecutar múltiples sentencias INSERT individuales para importar grandes volúmenes de datos. Está optimizado para la carga masiva de datos desde archivos.

Conclusión

Este artículo ha cubierto varias técnicas avanzadas esenciales en MySQL para administradores y desarrolladores. Hemos visto cómo aprovechar las sentencias SELECT para realizar inserciones y actualizaciones masivas, la importancia de las tablas temporales para preparar datos, el manejo de la eliminación de datos en presencia de clave externa utilizando la opción ON DELETE CASCADE (y sus riesgos), y las potentes herramientas LOAD DATA INFILE e INTO OUTFILE para importar y exportar datos de forma eficiente utilizando el formato CSV universal. Dominar estas habilidades te permitirá manejar escenarios de datos más complejos, integrar tu base de datos con fuentes externas y realizar tareas de administración de datos de manera más efectiva y eficiente. Estas actividades son comunes y vitales para gestionar grandes bases de datos en diversos entornos y plataformas.

Si quieres conocer otros artículos parecidos a MySQL Avanzado: Manipula Datos e Importa CSV puedes visitar la categoría MySQL.

Ivan

Soy un entusiasta de la tecnología con especialización en bases de datos, particularmente en MySQL. A través de mis tutoriales detallados, busco desmitificar los conceptos complejos y proporcionar soluciones prácticas a los desafíos cotidianos relacionados con la gestión de datos

Aprende mas sobre MySQL

Subir