MySQLトリガの紹介

5618 ワード

前言:
MySQLを学ぶ過程で、あなたはトリガの概念を知ったことがあるかもしれませんが、皆さんがトリガを詳しく勉強したことがあるかどうか分かりません.最近、トリガに関するドキュメントをいくつか見て、MySQLトリガに関する知識を共有しました.
1.トリガの概要
トリガはtriggersです.テーブルに関連するデータベース・オブジェクトで、定義条件を満たすとトリガーされ、トリガで定義された文のセットが実行されます.その実行は、プログラムによって呼び出されるのではなく、手動で起動されるのではなく、テーブルを操作(insert,delete,update)するとアクティブになります.トリガは、データの整合性制約やビジネス・ルールなどを強化するためによく使用されます.
公式ドキュメントを参照して、トリガによって作成される構文テンプレートは次のとおりです.
CREATE
    [DEFINER = user]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    [trigger_order]
    trigger_body

trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

トリガは永続テーブルにのみ作成でき、一時テーブルまたはビューにトリガを作成できません.トリガの名前は、単一のデータベース内で一意です.上記の文を参照してください.トリガの作成にはいくつかの要素があります.以下に簡単に説明します.
trigger_time:トリガ動作時間であり、BEFOREまたはAFTERであり、トリガが変更する各ローの前または後にアクティブになることを示します.
trigger_event:トリガをアクティブにする操作のタイプを示します.これらのtrigger_イベント値は許可されています.
  • insert:テーブルに新しいローを挿入すると、トリガがアクティブになります.たとえばinsert、load data、replace文です.
  • update:テーブル内の1行のデータを変更するとトリガーがアクティブになります.たとえばupdate文です.
  • delete:テーブルから1行のデータを削除するとトリガーがアクティブになります.たとえばdelete文とreplace文です.テーブルのDROP TABLE文とTRUNCATE TABLE文では、deleteを使用しないため、パーティションを削除してもdeleteトリガはアクティブになりません.

  • trigger_body:トリガがアクティブ化されたときに実行する文です.複数の文を実行する場合は、BEGIN...END複合文構造を使用します.トリガ本体では、oldおよびnewを使用して、トリガで変化した記録内容を参照できます.
    2.トリガの具体的な操作
    次に、トリガに関する具体的な操作を見てみましょう.
    #          
    mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
    Query OK, 0 rows affected (0.03 sec)
    mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
    
    mysql> delimiter //
    mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
           FOR EACH ROW
           BEGIN
               IF NEW.amount < 0 THEN
                   SET NEW.amount = 0;
               ELSEIF NEW.amount > 100 THEN
                   SET NEW.amount = 100;
               END IF;
           END;//
    mysql> delimiter ;
    
    #        
    mysql> select * from account;
    +----------+---------+
    | acct_num | amount  |
    +----------+---------+
    |      137 |   14.98 |
    |      141 | 1937.50 |
    |       97 | -100.00 |
    +----------+---------+
    3 rows in set (0.00 sec)
    
    mysql> update account set amount = 114.98 where acct_num = 137;
    Query OK, 1 row affected (0.01 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from account;
    +----------+---------+
    | acct_num | amount  |
    +----------+---------+
    |      137 |  100.00 |
    |      141 | 1937.50 |
    |       97 | -100.00 |
    +----------+---------+
    3 rows in set (0.00 sec)
    
    #      
    mysql> show triggers;
    
    #      
    mysql> drop trigger if exists upd_check;
    
    #              
    SELECT
        a.TRIGGER_SCHEMA,
        a.TRIGGER_NAME,
        a.ACTION_TIMING,
        a.EVENT_OBJECT_TABLE,
        a.EVENT_MANIPULATION 
    FROM
        information_schema.`TRIGGERS` a 
    WHERE
        a.TRIGGER_SCHEMA NOT IN ( 'information_schema', 'performance_schema', 'mysql', 'sys' );
      
    delimiter //   MySQL      ,   ;

    トリガの基本的な操作について説明しましたが、実際には、トリガは生産環境では珍しく、トリガの使用に一連の欠点があるため、データベースのニーズを解決することができても、いくつかの欠点を簡単にまとめます.
  • トリガを使用して実装されるビジネスロジックは、問題が発生した場合に位置決めが困難であり、特に複数のトリガに関連する場合、後期メンテナンスが困難になる.
  • フリップフロップの大量使用はコード構造の乱れを招きやすく、プログラムの複雑さを増加させ、
  • .
  • 変更が必要なデータ量が大きい場合、トリガの実行効率は非常に低くなります.
  • トリガ暗黙呼び出しは無視されやすく、問題が発生して調査しにくい.

  • しかし、トリガは役に立たないわけではありません.例えば、このテーブルのデータを削除したり更新したりしたくない場合は、トリガで実現できます.次のシーンでヒントを得ることができます.
    #              
    mysql> select * from student;
    +--------------+------+--------+-------+-------+
    | increment_id | s_id | s_name | s_sex | s_age |
    +--------------+------+--------+-------+-------+
    |            1 | 1001 | sdfsd  |      |    18 |
    |            2 | 1003 | zsdfsd |      |    19 |
    +--------------+------+--------+-------+-------+
    2 rows in set (0.00 sec)
    
    mysql> delimiter //
    mysql> CREATE TRIGGER `tri_delstu` BEFORE DELETE ON `student` FOR EACH ROW begin
        -> declare msg varchar(255);
        -> set msg="         ";
        -> SIGNAL SQLSTATE 'HY000' SET  MESSAGE_TEXT = msg;
        -> end; //
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> delimiter ;
    mysql> delete from student where s_id = 1003;
    ERROR 1644 (HY000):          
    
    #         
    mysql> delimiter //
    mysql> CREATE TRIGGER trg__updateSid BEFORE UPDATE ON `student`
        -> FOR EACH ROW
        -> BEGIN
        ->  DECLARE msg VARCHAR(100); 
        ->  IF NEW.s_id <> OLD.s_id THEN
        ->  SET msg='       '; 
        ->  SIGNAL SQLSTATE 'HY000' SET message_text = msg; 
        ->  END IF; 
        -> END; //
    Query OK, 0 rows affected (0.06 sec)
    
    mysql> delimiter ;
    mysql> update student set s_id = 1002 where increment_id = 2;
    ERROR 1644 (HY000):        
    
    #       
    mysql> delimiter //
    mysql> CREATE TRIGGER `tri_update_age` BEFORE UPDATE ON `student` FOR EACH ROW BEGIN
        ->         DECLARE msg VARCHAR(20);
        ->   IF (NEW.s_age<0) THEN 
        ->         set msg="      0";
        ->   signal sqlstate 'HY000' set message_text=msg;
        ->         END IF;
        -> END; //
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> delimiter ;
    mysql> update student set s_age=10 where s_id = 1001;
    Query OK, 1 row affected (0.01 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> update student set s_age=-10 where s_id = 1001;
    ERROR 1644 (HY000):       0

    まとめ:
    この記事では、トリガの定義と使用例について簡単に説明します.ビジネスロジックが複雑なシステムやテーブルの変動が頻繁なシステムでは、トリガの使用を推奨しません.もちろん、独自のアプリケーションシーンもあります.いずれにしても、トリガのロジックは常に簡単であればあるほど、データベースに得意なことをさせなければなりません.すべてのロジックがデータベースレベルで実現されるとは考えられません.