Mysql
 sql >> Database >  >> RDS >> Mysql

Stored procedure che eliminano automaticamente le righe più vecchie di 7 giorni in MySQL

Mysql ha la sua funzionalità EVENT per evitare complicate interazioni cron quando gran parte di ciò che stai pianificando è correlato a sql e meno correlato ai file. Consulta la pagina del manuale qui . Si spera che quanto segue sia una rapida panoramica dei passaggi importanti e delle cose da considerare e anche dei test verificabili.

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

ooops, l'utilità di pianificazione degli eventi non è attivata. Non si attiverà nulla.

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

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

Schema per il test

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 eventi, 1a corsa al giorno, 2a corsa ogni 10 minuti

Ignora ciò che stanno effettivamente facendo (giocando l'uno contro l'altro). Il punto è su time difference approcci e programmazione .

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 ;

Mostra gli stati degli eventi (approcci diversi)

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)

Cose casuali da considerare

drop event someEventName; -- <----- una buona cosa da sapere

non può alias datediff e utilizzare in where clausola in 1 riga, quindi

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

ottenere più esatti, 168 ore per 1 settimana

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

Il collegamento alla pagina del manuale mostra un po' di flessibilità con le scelte di intervallo, mostrate di seguito:

intervallo:

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

Concorrenza

Incorpora tutte le misure di concorrenza necessarie affinché più eventi (o più attivazioni dello stesso evento) non causino l'esaurimento dei dati.

Imposta e dimentica

Ricorda, per ora, perché te lo dimenticherai, che questi eventi continuano a sparare. Quindi costruisci un codice solido che continuerà a funzionare, anche quando te lo dimentichi. Cosa che molto probabilmente farai.

Le tue esigenze particolari

È necessario determinare quali righe devono essere eliminate per prime dalla tabella, in modo che rispetti i vincoli della chiave primaria. Basta raggrupparli tutti nell'ordine corretto all'interno dell'area ovvia tramite l'istruzione CREATE EVENT, che può essere enorme.