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

Lagret procedure, der automatisk sletter rækker ældre end 7 dage i MYSQL

Mysql har sin EVENT-funktionalitet til at undgå komplicerede cron-interaktioner, når meget af det, du planlægger, er sql-relateret og mindre filrelateret. Se manualsiden her . Forhåbentlig kan nedenstående læses som et hurtigt overblik over de vigtige trin og ting, der skal overvejes, og også verificerbare tests.

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

ups, begivenhedsplanlæggeren er ikke slået til. Intet vil udløse.

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

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

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

Opret 2 begivenheder, 1. kørsel dagligt, 2. kørsel hvert 10. minut

Ignorer, hvad de rent faktisk gør (spiller mod hinanden). Pointen er time difference tilgange og planlægning .

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 ;

Vis hændelsesstatusser (forskellige tilgange)

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)

Tilfældige ting at overveje

drop event someEventName; -- <----- en god ting at vide om

kan ikke alias datediff og bruge in where-sætning i 1 linje, så

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

få mere præcis, 168 timer for 1 uge gammel

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

Linket til manualsiden viser en del fleksibilitet med intervalvalg, vist nedenfor:

interval:

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

Samtidig

Integrer eventuelle samtidighedsforanstaltninger, der er nødvendige for, at flere hændelser (eller flere affyringer af samme hændelse) ikke får data til at løbe amok.

Indstil og glem

Husk, for nu, fordi du kommer til at glemme det, at disse begivenheder bare bliver ved med at skyde. Så indbygg en solid kode, der bare fortsætter med at køre, selv når du glemmer det. Hvilket du højst sandsynligt vil.

Dine særlige krav

Du skal bestemme, hvilke rækker der skal slettes først efter tabel, således at den overholder Primærnøgle-begrænsninger. Bare klump dem alle sammen i den rigtige rækkefølge inde i det åbenlyse område via CREATE EVENT-erklæringen, som kan være massiv.



  1. En tilgang til indeksjustering – del 2

  2. SQLite og database initialisering

  3. Kloning af databaser med PSDatabaseClone

  4. Rails Migration:Bigint på PostgreSQL ser ud til at fejle?