Quantcast
Channel: El Club del Programador
Viewing all articles
Browse latest Browse all 18

Moviendo registros entre tablas de forma segura con MySQL

$
0
0

Las aplicaciones que necesitan copiar registros de una tabla a otra en MySQL sólo necesitan realizar utilizar serie de operaciones del tipo INSERT…. SELECT para obtener los registros desde la tabla origen y poder añadirlos a la tabla destino, pero si la aplicación necesita mover los registros (que no copiar) el proceso se torna un poco más complicado. Después de copiar las filas en la tabla de destino, debemos removerlas de la tabla origen. De forma conceptual no es más que INSERT / SELECT / DELETE, pero en la practica se podría necesitar de más cuidado ya que será necesario seleccionar exactamente el mismo conjunto de filas que la tabla origen para ambas sentencias ( nos referimos al INSERT y DELETE).

Supongamos que nuestra aplicación utiliza una tabla para registrar toda la actividad que se realiza diariamente. De forma períodica ( como tarea de housekeeping) tenemos que mover los registros de log de nuestra tabla principal a nuestra tabla de “respaldo” para mantener de forma optima el tamaño de nuestra tabla principal, además que nos permitirá realizar cuantiosos analisis de comportamiento sin bloquear los procesos que crean nuevos registros en la tabla principal. ¿Como afrontamos esto?

 

Solución genérica

Lo primero que nos llega a la cabeza es implementar una solución de la forma:

1
2
INSERT INTO backupLog SELECT * FROM worklog;
DELETE FROM worklog;

Esta estrategia funciona de forma correcta si tu aplicación sólo es accedidamuy pocas veces o la inserción de registros en el log no ocurre de forma tan seguida ( por ejemplo entre las sentencias INSERT y SELECT), pero si por el contrario, tu aplicacion es utilizada de forma recurrente esta implementación no será una buena estrategia ya que perderemos registros, si sólo es trazas de acceso a una aplicación no puede ser tan grave, pero imagina si son transacciones financieras, simplemente nos meteriamos en un serio aprieto.

 

Segundo Intento

Entonces ¿Que debemos hacer para no perder registros? Tenemos 2 posibilidades, la primera bloquear ambas tablas que usemos (no vamos a tratar este tema en este artículo). La segunda es mover sólo aquellos registros que sean más antiguos que un punto especifico en el tiempo. Por ejemplo podemos añadir a nuestra tabla de logs una columna llamada “tiempo” del tipo timestamp y limitar el scope de los registros a seleccionar a todos aquellos creados antes de determinada fecha.

1
2
INSERT INTO backupLog SELECT * FROM worklog WHERE tiempo < CURDATE( );
DELETE FROM worklog WHERE tiempo < CURDATE( );

Mucho mejor no?, Pero ahora imagnemos lo siguiente, Supongamos que especificamos la tarea de mover los registros a una determinada hora (00 Horas por ejemplo), si el INSERT se realiza antes de dicha hora y el SELECT justo después el valor de retorno del método CURDATE() será diferente por lo que la operación de borrado podrá remover muchos más registros. Para evitar estos “gaps” vamos a refinar nuestro método anterior.

Estrategia final

Para curarnos en salud, simplemente almacenamos el valor de nuestro “punto de corte” para asegurarnos que siempre sea el mismo, de la forma:

1
2
3
SET @corte= CURDATE( );
INSERT INTO backupLog SELECT * FROM worklog WHERE tiempo < @corte;
DELETE FROM worklog WHERE tiempo < @corte;

 

Te puede interesar:

Registra todos los comandos que ejecutas con MySQL
Muestra resultados más legibles en tus consultas en MySQL
Habilitando el Auto-completado con MySQL


Viewing all articles
Browse latest Browse all 18

Trending Articles