sql >> Base de Datos >  >> RDS >> Mysql

Procedimiento almacenado que elimina automáticamente filas de más de 7 días en MYSQL

Mysql tiene su funcionalidad EVENT para evitar interacciones cron complicadas cuando gran parte de lo que está programando está relacionado con sql y menos relacionado con archivos. Consulte la página del Manual aquí . Esperemos que lo siguiente se lea como una descripción general rápida de los pasos importantes y las cosas a considerar, y también de las pruebas verificables.

show variables where variable_name='event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |
+-----------------+-------+

Vaya, el programador de eventos no está activado. Nada se activará.

SET GLOBAL event_scheduler = ON; -- turn her on and confirm below

show variables where variable_name='event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | ON    |
+-----------------+-------+

Esquema para pruebas

create table theMessages
(   id int auto_increment primary key,
    userId int not null,
    message varchar(255) not null,
    updateDt datetime not null,
    key(updateDt)
    -- FK's not shown
);
-- it is currently 2015-09-10 13:12:00
-- truncate table theMessages;
insert theMessages(userId,message,updateDt) values (1,'I need to go now, no followup questions','2015-08-24 11:10:09');
insert theMessages(userId,message,updateDt) values (7,'You always say that ... just hiding','2015-08-29');
insert theMessages(userId,message,updateDt) values (1,'7 day test1','2015-09-03 12:00:00');
insert theMessages(userId,message,updateDt) values (1,'7 day test2','2015-09-03 14:00:00');

Crea 2 eventos, la primera se ejecuta diariamente, la segunda se ejecuta cada 10 minutos

Ignora lo que están haciendo en realidad (jugando unos contra otros). El punto está en time difference enfoques y programación .

DELIMITER $$
CREATE EVENT `delete7DayOldMessages`
  ON SCHEDULE EVERY 1 DAY STARTS '2015-09-01 00:00:00'
  ON COMPLETION PRESERVE
DO BEGIN
   delete from theMessages 
   where datediff(now(),updateDt)>6; -- not terribly exact, yesterday but <24hrs is still 1 day
   -- etc etc all your stuff in here
END;$$
DELIMITER ;

...

DELIMITER $$
CREATE EVENT `Every_10_Minutes_Cleanup`
  ON SCHEDULE EVERY 10 MINUTE STARTS '2015-09-01 00:00:00'
  ON COMPLETION PRESERVE
DO BEGIN
   delete from theMessages 
   where TIMESTAMPDIFF(HOUR, updateDt, now())>168; -- messages over 1 week old (168 hours)
   -- etc etc all your stuff in here
END;$$
DELIMITER ;

Mostrar estados de eventos (diferentes enfoques)

show events from so_gibberish; -- list all events by schema name (db name)
show events; -- <--------- from workbench / sqlyog
show events\G;` -- <--------- I like this one from mysql> prompt

*************************** 1. row ***************************
                  Db: so_gibberish
                Name: delete7DayOldMessages
             Definer: [email protected]
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 1
      Interval field: DAY
              Starts: 2015-09-01 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
*************************** 2. row ***************************
                  Db: so_gibberish
                Name: Every_10_Minutes_Cleanup
             Definer: [email protected]
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 10
      Interval field: MINUTE
              Starts: 2015-09-01 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
2 rows in set (0.06 sec)

Cosas aleatorias a tener en cuenta

drop event someEventName; -- <----- algo bueno que saber

no se puede usar un alias de fechadoiff y usar la cláusula in where en 1 línea, entonces

select id,DATEDIFF(now(),updateDt) from theMessages where datediff(now(),updateDt)>6;

ser más exacto, 168 horas para 1 semana

select id,TIMESTAMPDIFF(HOUR, updateDt, now()) as `difference` FROM theMessages;
+----+------------+
| id | difference |
+----+------------+
|  1 |        410 |
|  2 |        301 |
|  3 |        169 |
|  4 |        167 |
+----+------------+

El enlace a la página del manual muestra bastante flexibilidad con las opciones de intervalo, como se muestra a continuación:

intervalo:

quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
          WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
          DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

Concurrencia

Incruste cualquier medida de concurrencia necesaria para que múltiples eventos (o múltiples disparos del mismo evento) no provoquen que los datos se vuelvan locos.

Establecer y olvidar

Recuerda, por ahora, porque lo vas a olvidar, que estos eventos siguen disparándose. Así que construye un código sólido que seguirá ejecutándose, incluso cuando lo olvides. Lo que probablemente harás.

Sus requisitos particulares

Debe determinar qué filas deben eliminarse primero por tabla, de modo que respete las restricciones de clave principal. Simplemente agréguelos en el orden correcto dentro del área obvia a través de la declaración CREATE EVENT, que puede ser enorme.