当前位置: 首页 > 面试题库 >

自动删除MYSQL中7天以上的行的存储过程

郭星文
2023-03-14
问题内容

我想知道是否有可能创建一个存储过程,该存储过程在每天的00:00自动删除超过7天的每个表的每一行。

我见过很少的解决方案,但不确定是否是我想要的,如果有人有很好的榜样,那会很好。我知道可以使用python和php中的简单脚本来完成此操作,但是我想通过MySQL自动化一些。

任何帮助将不胜感激。

谢谢!


问题答案:

Mysql具有其EVENT功能,可避免您计划的大部分与sql有关,而与文件无关的情况下避免复杂的cron交互。请参见此处的手册页面。希望以下内容可以作为重要步骤和要考虑事项以及可验证测试的简要概述。

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

糟糕,事件调度程序未打开。什么都不会触发。

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

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

测试架构

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

创建2个事件,每天运行1次,每10分钟运行2次

忽略他们实际在做什么(互相对抗)。重点是time difference方法和 调度

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 ;

显示事件状态(不同的方法)

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: root@localhost
           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: root@localhost
           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)

随机的东西要考虑

drop event someEventName; -<-----要了解的一件好事

无法别名datediff并在1行的where子句中使用,因此

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

获得更精确的信息,1周龄为168小时

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

手册页的链接显示了很多灵活的间隔选择,如下所示:

间隔:

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

并发

嵌入所有必要的并发措施,以确保多个事件(或同一事件的多次触发)不会导致数据无法正常运行。

设置并忘记

请记住,现在,因为您将忘记它,所以这些事件一直在触发。因此,即使您忘了,也要构建可靠的代码以保持运行。您最有可能会。

您的特殊要求

您需要确定哪些表首先需要由表删除,以使其符合主键约束。只需通过CREATE EVENT语句将它们全部按适当顺序放在明显区域内即可,这可能会很大。



 类似资料:
  • 存储过程被创建后,就会一直保存在数据库服务器上,直至被删除。当 MySQL 数据库中存在废弃的存储过程时,我们需要将它从数据库中删除。 MySQL 中使用 DROP PROCEDURE 语句来删除数据库中已经存在的存储过程。语法格式如下: DROP PROCEDURE [ IF EXISTS ] <过程名> 语法说明如下: 过程名:指定要删除的存储过程的名称。 IF EXISTS:指定这个关键字,

  • 我目前正在运行一个bash脚本,使用curl在Github上自动创建一个远程存储库。我想知道是否有任何方法也可以删除命令行上的远程Github存储库。任何帮助将不胜感激!

  • 问题内容: 我在存储过程中创建一个动态查询。我的存储过程如下: 当我尝试通过以下调用运行它时: 我收到以下错误消息: 错误代码:1054。“ where子句”中的未知列“ SPA” 我在没有where条件的情况下进行了测试,并且工作正常,但是在where条件不起作用的情况下,我尝试使用@和变量名一起使用,但仍然无法正常工作。 谢谢你的帮助。 问题答案: 您错过了条款中的引号。 尝试这样: 说明 :

  • 我正在开发一个保存更多帐户的应用程序。我不用数据库但我用文件...我的问题是是否可以更改或删除单行文件txt在我的手机存储???

  • 问题内容: 我在任何地方都找不到此答案,但是可以从MySQL中的另一个存储过程调用存储过程吗?我想找回标识值,并在父存储过程中使用它。我们不能再使用FUNCTIONS! 问题答案: 参数应该可以帮助您将值返回给调用过程。基于此,解决方案必须是这样的。

  • 问题内容: 我在使用InnoDB的MySQL中有一个表,其中有一列名为“ id”的列。 所以我的问题是,每当我从表中删除最后一行然后插入新值时,新值都会在删除的ID之后插入。 我的意思是假设我的id是32,我想删除它,然后如果我在删除后插入新行,则列id会自动递增到33。因此序列格式被破坏了,即id = 30,31,33而且不是32。 因此,当我删除最后一列后插入时,请帮我分配ID 32(而不是3