sql >> Databasteknik >  >> RDS >> Mysql

Lagrad procedur som automatiskt tar bort rader äldre än 7 dagar i MYSQL

Mysql har sin EVENT-funktion för att undvika komplicerade cron-interaktioner när mycket av det du schemalägger är sql-relaterat och mindre filrelaterat. Se manualsidan här . Förhoppningsvis läses nedanstående som en snabb översikt över de viktiga stegen och sakerna att tänka på, och verifierbara tester också.

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

oj, händelseschemaläggaren är inte påslagen. Ingenting kommer att utlösas.

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 för testning

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

Skapa 2 evenemang, 1:a körning dagligen, 2:a körning var 10:e minut

Ignorera vad de faktiskt gör (spelar mot varandra). Poängen är time difference tillvägagångssätt och schemaläggning .

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 ;

Visa händelsestatus (olika tillvägagångssätt)

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)

Slumpmässiga saker att överväga

drop event someEventName; -- <----- bra att veta om

kan inte alias datediff och använda in where-sats på 1 rad, så

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

få mer exakt, 168 timmar för 1 vecka gamla

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

Länken till manualsidan visar en hel del flexibilitet med intervallval, som visas nedan:

intervall:

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

Samtidighet

Bädda in eventuella samtidighetsåtgärder som krävs för att flera händelser (eller flera avfyrningar av samma händelse) inte får data att gå amok.

Ställ in och glöm

Kom ihåg, för nu, eftersom du kommer att glömma det, att dessa händelser bara fortsätter att brinna. Så bygg in solid kod som bara fortsätter att köras, även när du glömmer det. Vilket du med största sannolikhet kommer att göra.

Dina särskilda krav

Du måste bestämma vilka rader som måste tas bort först efter tabell, så att den respekterar primärnyckelbegränsningar. Klumpa ihop dem alla i rätt ordning i det uppenbara området via CREATE EVENT-satsen, som kan vara enorm.



  1. Varför stöder inte MySQL millisekund / mikrosekund precision?

  2. FEL 1130 (HY000):Värden '' får inte ansluta till denna MySQL-server

  3. SqlConnection SqlCommand SqlDataReader ID Disposable

  4. JOIN (VÄLJ ... ) ue PÅ 1=1?