Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Gespeicherte Prozedur, die automatisch Zeilen löscht, die älter als 7 Tage in MYSQL sind

Mysql hat seine EVENT-Funktionalität, um komplizierte Cron-Interaktionen zu vermeiden, wenn viel von dem, was Sie planen, mit SQL und weniger mit Dateien zu tun hat. Siehe Handbuchseite hier . Hoffentlich liest sich das Folgende als schneller Überblick über die wichtigen Schritte und Dinge, die es zu beachten gilt, sowie über verifizierbare Tests.

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

Hoppla, der Ereignisplaner ist nicht aktiviert. Nichts wird ausgelöst.

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 zum Testen

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

Erstellen Sie 2 Ereignisse, 1. läuft täglich, 2. läuft alle 10 Minuten

Ignorieren Sie, was sie tatsächlich tun (gegeneinander spielen). Der Punkt ist auf time difference Ansätze und Zeitplanung .

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 ;

Ereignisstatus anzeigen (verschiedene Ansätze)

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)

Zufällige Dinge, die berücksichtigt werden sollten

drop event someEventName; -- <----- gut zu wissen

kann datediff nicht aliasieren und in where-Klausel in 1 Zeile verwenden, also

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

Genauer gesagt, 168 Stunden für 1 Woche alt

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

Der Link zur Handbuchseite zeigt ziemlich viel Flexibilität bei der Auswahl der Intervalle, siehe unten:

Intervall:

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

Gleichzeitigkeit

Integrieren Sie alle Maßnahmen zur Parallelität, die erforderlich sind, damit mehrere Ereignisse (oder mehrere Auslösungen desselben Ereignisses) nicht dazu führen, dass Daten Amok laufen.

Einstellen und vergessen

Denken Sie vorerst daran, weil Sie es vergessen werden, dass diese Ereignisse einfach weiterfeuern. Bauen Sie also soliden Code ein, der einfach weiterläuft, selbst wenn Sie es vergessen. Was Sie höchstwahrscheinlich tun werden.

Ihre speziellen Anforderungen

Sie müssen bestimmen, welche Zeilen zuerst nach Tabelle gelöscht werden müssen, damit die Primärschlüsseleinschränkungen eingehalten werden. Fassen Sie sie einfach alle in der richtigen Reihenfolge innerhalb des offensichtlichen Bereichs über die CREATE EVENT-Anweisung zusammen, die sehr umfangreich sein kann.