sql >> Database >  >> RDS >> Mysql

Opgeslagen procedure die automatisch rijen verwijdert die ouder zijn dan 7 dagen in MYSQL

Mysql heeft zijn EVENT-functionaliteit om gecompliceerde cron-interacties te vermijden wanneer veel van wat u plant sql-gerelateerd is en minder file-gerelateerd. Zie de pagina met de handleiding hier . Hopelijk leest het onderstaande als een snel overzicht van de belangrijke stappen en dingen om te overwegen, en ook als verifieerbaar testen.

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

oeps, de evenementenplanner is niet ingeschakeld. Er wordt niets geactiveerd.

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

Maak 2 evenementen, 1e runs dagelijks, 2e runs elke 10 minuten

Negeer wat ze eigenlijk aan het doen zijn (tegen elkaar spelen). Het punt is op time difference benaderingen en planning .

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 ;

Toon gebeurtenisstatussen (verschillende benaderingen)

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)

Willekeurige dingen om te overwegen

drop event someEventName; -- <----- goed om te weten

kan datediff niet aliasen en gebruiken in where-clausule in 1 regel, dus

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

nauwkeuriger worden, 168 uur voor 1 week oud

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

De link naar de handleidingpagina toont nogal wat flexibiliteit met intervalkeuzes, zoals hieronder weergegeven:

interval:

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

Gelijktijdigheid

Sluit alle gelijktijdigheidsmaatregelen in die nodig zijn zodat meerdere gebeurtenissen (of meerdere activeringen van dezelfde gebeurtenis) er niet toe leiden dat gegevens op hol slaan.

Instellen en vergeten

Onthoud, voor nu, omdat je het gaat vergeten, dat deze gebeurtenissen maar blijven vuren. Dus bouw solide code in die gewoon blijft draaien, zelfs als je het vergeet. Wat u hoogstwaarschijnlijk ook zult doen.

Uw specifieke vereisten

U moet per tabel bepalen welke rijen eerst moeten worden verwijderd, zodat deze voldoet aan de beperkingen van de primaire sleutel. Zet ze gewoon allemaal in de juiste volgorde in het voor de hand liggende gebied via de CREATE EVENT-instructie, die enorm kan zijn.



  1. Hoe duplicaten op een MySQL-tabel te verwijderen?

  2. Inleiding tot Inline Table-Valued Functions (ITVF) in SQL Server

  3. Verbinding maken met de database vanuit Unity

  4. Een berekende kolom maken die gegevens uit een andere tabel in SQL Server gebruikt