Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Procedimento armazenado que exclui automaticamente linhas com mais de 7 dias no MYSQL


O Mysql tem sua funcionalidade EVENT para evitar interações cron complicadas quando muito do que você está agendando é relacionado ao sql e menos relacionado ao arquivo. Consulte a página do Manual aqui . Espero que o abaixo seja lido como uma visão geral rápida das etapas e coisas importantes a serem consideradas, e testes verificáveis ​​também.
show variables where variable_name='event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |
+-----------------+-------+

ooops, o agendador de eventos não está ativado. Nada vai desencadear.

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 teste

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');

Crie 2 eventos, 1ª corrida diariamente, 2ª corrida a cada 10 minutos


Ignore o que eles estão realmente fazendo (jogando um contra o outro). O ponto está na time difference abordagens e agendamento .
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 status do evento (diferentes abordagens)

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)

Coisas aleatórias a serem consideradas


drop event someEventName; -- <----- uma coisa boa para saber sobre

não pode alias dateiff e usar cláusula where em 1 linha, então
select id,DATEDIFF(now(),updateDt) from theMessages where datediff(now(),updateDt)>6;

obter mais exato, 168 horas para 1 semana de idade
select id,TIMESTAMPDIFF(HOUR, updateDt, now()) as `difference` FROM theMessages;
+----+------------+
| id | difference |
+----+------------+
|  1 |        410 |
|  2 |        301 |
|  3 |        169 |
|  4 |        167 |
+----+------------+

O link para a página do manual mostra bastante flexibilidade com as opções de intervalo, mostradas abaixo:

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

Simultaneidade


Incorpore todas as medidas de simultaneidade necessárias para que vários eventos (ou vários disparos do mesmo evento) não causem o descontrole dos dados.

Definir e esquecer


Lembre-se, por enquanto, porque você vai esquecer, que esses eventos continuam disparando. Portanto, crie um código sólido que continuará em execução, mesmo quando você esquecer. O que você provavelmente fará.

Seus requisitos específicos


Você precisa determinar quais linhas precisam ser excluídas primeiro pela tabela, de modo que ela honre as restrições de chave primária. Basta agrupar todos eles na ordem correta dentro da área óbvia por meio da instrução CREATE EVENT, que pode ser enorme.