sql >> Databáze >  >> RDS >> Mysql

Uložená procedura, která automaticky odstraňuje řádky starší než 7 dní v MYSQL

Mysql má svou funkci EVENT, aby se zabránilo komplikovaným interakcím cronu, když velká část toho, co plánujete, souvisí s SQL a méně se soubory. Viz manuálovou stránku zde . Doufejme, že níže uvedený text slouží jako rychlý přehled důležitých kroků a věcí, které je třeba zvážit, a také ověřitelné testování.

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

ooops, plánovač událostí není zapnutý. Nic se nespustí.

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 pro testování

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

Vytvořte 2 události, 1. spuštění denně, 2. spuštění každých 10 minut

Ignorujte, co vlastně dělají (hrají proti sobě). Jde o time difference přístupy a plánování .

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 ;

Zobrazit stavy událostí (různé přístupy)

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)

Náhodné věci ke zvážení

drop event someEventName; -- <----- dobrá věc, o které byste měli vědět

can't alias datediff a use in where klauzule v 1 řádku, takže

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

získat přesnější, 168 hodin pro 1 týden staré

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

Odkaz na manuálovou stránku ukazuje docela dost flexibility s volbami intervalů, jak je uvedeno níže:

interval:

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

Souběh

Zaveďte všechna potřebná opatření souběžnosti, aby více událostí (nebo vícenásobné spuštění stejné události) nezpůsobilo šílenství dat.

Nastavit a zapomenout

Pro tuto chvíli si pamatujte, protože na to zapomenete, že tyto události stále pálí. Vytvořte si tedy pevný kód, který bude stále běžet, i když zapomenete. Což s největší pravděpodobností uděláte.

Vaše konkrétní požadavky

Musíte určit, které řádky je třeba podle tabulky odstranit jako první, aby dodržovala omezení primárního klíče. Stačí je všechny umístit ve správném pořadí do zjevné oblasti pomocí příkazu CREATE EVENT, který může být obrovský.



  1. Skript pro uložení varbinárních dat na disk

  2. Příklady FROM_UNIXTIME() – MySQL

  3. Postgresql generuje_řadu měsíců

  4. Úvod do Storage Spaces Direct pro SQL Server