sql >> データベース >  >> RDS >> Mysql

MYSQLで7日より古い行を自動的に削除するストアドプロシージャ

    Mysqlには、スケジュールしている内容の多くがSQL関連であり、ファイル関連が少ない場合に、複雑なcronの相互作用を回避するためのEVENT機能があります。マニュアルページこちら を参照してください。 。うまくいけば、以下は重要なステップと考慮すべき事柄の簡単な概要、そして検証可能なテストとしても読めます。

    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回目は毎日実行し、2回目は10分ごとに実行します

    彼らが実際に行っていることを無視します(お互いに対戦します)。ポイントは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: [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)
    

    考慮すべきランダムなもの

    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}
    

    並行性

    複数のイベント(または同じイベントの複数の発生)によってデータが正常に実行されないようにするために必要な同時実行手段を埋め込みます。

    設定して忘れる

    今のところ、あなたはそれを忘れようとしているので、これらのイベントはただ発火し続けることを忘れないでください。したがって、忘れた場合でも実行を継続する堅実なコードを組み込みます。おそらくどちらでしょう。

    特定の要件

    主キーの制約を尊重するように、テーブルごとに最初に削除する必要がある行を決定する必要があります。大量になる可能性のあるCREATEEVENTステートメントを使用して、明らかな領域内にすべてを適切な順序でまとめるだけです。



    1. 失敗したすべてのSQLステートメントをOracle10Gに記録する方法はありますか

    2. MySQL-選択時に行番号を取得

    3. OracleでQuarterFromDateを取得するにはどうすればよいですか?

    4. データベーススキーマオブジェクトチェックの自動化