Mysql
 sql >> Base de données >  >> RDS >> Mysql

Procédure stockée qui supprime automatiquement les lignes de plus de 7 jours dans MYSQL

Mysql a sa fonctionnalité EVENT pour éviter les interactions cron compliquées lorsqu'une grande partie de ce que vous planifiez est liée à sql et moins liée aux fichiers. Voir la page du manuel ici . Espérons que ce qui suit se présente comme un aperçu rapide des étapes importantes et des éléments à prendre en compte, ainsi que des tests vérifiables également.

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

oups, le planificateur d'événements n'est pas activé. Rien ne se déclenchera.

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

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

Schéma de 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');

Créer 2 événements, 1er passages quotidiens, 2e passages toutes les 10 minutes

Ignorez ce qu'ils font réellement (jouer les uns contre les autres). Le point est sur le time difference approches et planification .

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 ;

Afficher les statuts des événements (différentes approches)

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)

Choses aléatoires à prendre en compte

drop event someEventName; -- <----- une bonne chose à savoir

ne peut pas alias datediff et utiliser la clause where dans 1 ligne, donc

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

obtenir plus précis, 168 heures pour 1 semaine

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

Le lien vers la page du manuel montre un peu de flexibilité avec les choix d'intervalles, illustrés ci-dessous :

intervalle :

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

Concurrence

Intégrez toutes les mesures de simultanéité nécessaires pour que plusieurs événements (ou plusieurs déclenchements du même événement) ne provoquent pas de dysfonctionnement des données.

Définir et oublier

Rappelez-vous, pour l'instant, parce que vous allez l'oublier, que ces événements ne cessent de se déclencher. Alors construisez un code solide qui continuera à fonctionner, même lorsque vous oubliez. Ce que vous ferez très probablement.

Vos exigences particulières

Vous devez déterminer quelles lignes doivent être supprimées en premier par table, de sorte qu'elle respecte les contraintes de clé primaire. Regroupez-les simplement dans le bon ordre à l'intérieur de la zone évidente via l'instruction CREATE EVENT, qui peut être massive.