MySQL 트리거란 정확히 무엇입니까? MySQL은 트리거를 생성합니다(CREATE TRIGGER)

저장 프로시저와 마찬가지로 MySQL 트리거는 MySQL에 포함된 프로그램이며 MySQL의 데이터 관리를 위한 강력한 도구입니다. 차이점은 저장 프로시저를 실행하려면 CALL 문을 사용해야 하지만, 트리거를 실행하려면 CALL 문을 사용하지 않고 수동으로 시작할 필요도 없으며 대신 트리거되어 활성화됩니다. 데이터 테이블의 관련 작업을 통해 실행을 달성합니다. 예를 들어, 학생 테이블에 작업(INSERT, DELETE 또는 UPDATE)이 수행되면 활성화됩니다.

트리거는 데이터 테이블과 밀접한 관련이 있으며 주로 테이블의 데이터를 보호하는 데 사용됩니다. 특히 서로 관련된 여러 테이블이 있는 경우 트리거는 서로 다른 테이블의 데이터 일관성을 유지할 수 있습니다.

MySQL에서는 INSERT, UPDATE, DELETE 작업을 수행할 때만 트리거가 활성화될 수 있으며, 다른 SQL 문에서는 트리거가 활성화되지 않습니다.

그렇다면 트리거를 사용하는 이유는 무엇입니까? 예를 들어, 실제로 프로젝트를 개발하다 보면 다음과 같은 상황에 자주 직면하게 됩니다.

  • 학생에 대한 기록이 학생 테이블에 추가되면 총 학생 수도 변경되어야 합니다.
  • 학생 기록을 추가할 때 연령이 범위 요구 사항을 충족하는지 확인해야 합니다.
  • 학생정보 삭제 시 해당 성적표의 기록도 삭제되어야 합니다.
  • 데이터 일부가 삭제되면 데이터베이스 아카이브 테이블에 백업 복사본을 보관해야 합니다.

 
위 상황에서 구현되는 비즈니스 로직은 다르지만 모두 데이터 테이블이 변경되면 일부 처리를 자동으로 수행해야 합니다. 이때 트리거 처리를 사용할 수 있습니다. 예를 들어 첫 번째 경우에는 트리거 개체를 생성하고 학생 기록이 추가될 때마다 총 학생 수를 계산하는 작업을 수행할 수 있습니다. 학생 기록 수가 계산됩니다.

트리거의 장점과 단점

트리거의 장점은 다음과 같습니다.

  • 트리거 실행은 자동으로 이루어지며, 트리거 관련 테이블의 데이터가 해당 수정된 직후에 실행됩니다.
  • 트리거는 FOREIGN KEY 제약 조건 및 CHECK 제약 조건보다 더 복잡한 검사 및 작업을 구현할 수 있습니다.
  • 트리거는 테이블 데이터에 대한 계단식 변경을 구현하여 어느 정도 데이터 무결성을 보장할 수 있습니다.


트리거의 단점은 다음과 같습니다.

  • 트리거를 사용하여 구현된 비즈니스 논리는 문제가 발생할 때 찾기 어렵고, 특히 여러 트리거가 관련된 경우 나중에 유지 관리가 어렵습니다.
  • 트리거를 광범위하게 사용하면 코드 구조가 쉽게 중단되고 프로그램이 더 복잡해질 수 있습니다.
  • 변경해야 하는 데이터의 양이 많으면 트리거의 실행 효율성이 매우 낮아집니다.

MySQL에서 지원하는 트리거

실제 사용에서 MySQL은 INSERT 트리거, UPDATE 트리거, DELETE 트리거의 세 가지 트리거를 지원합니다.

1) INSERT 트리거

INSERT 문이 실행되기 전이나 후에 응답하는 트리거입니다.

INSERT 트리거를 사용할 때 다음 사항에 주의해야 합니다.

  • INSERT 트리거 코드 내에서 NEW(대소문자 구분 안 함)라는 가상 테이블을 참조하여 삽입된 행에 액세스할 수 있습니다.
  • BEFORE INSERT 트리거에서는 NEW의 값도 업데이트될 수 있으며, 이를 통해 삽입된 값을 변경할 수 있습니다(해당 작업 권한이 있는 경우).
  • AUTO_INCREMENT 열의 경우 NEW에는 INSERT가 실행되기 전에 값 0이 포함되고 INSERT가 실행된 후에 자동으로 생성된 새 값이 포함됩니다.
2) 업데이트 트리거

UPDATE 문이 실행되기 전이나 후에 응답하는 트리거입니다.

UPDATE 트리거를 사용할 때 다음 사항에 주의해야 합니다.

  • UPDATE 트리거 코드 내에서 NEW(대소문자 구분 안 함)라는 가상 테이블을 참조하여 업데이트된 값에 액세스할 수 있습니다.
  • UPDATE 트리거 코드 내에서 OLD(대소문자 구분 안 함)라는 가상 테이블을 참조하여 UPDATE 문이 실행되기 전의 값에 액세스할 수 있습니다.
  • BEFORE UPDATE 트리거에서는 NEW의 값도 업데이트될 수 있으며, 이를 통해 UPDATE 문에서 사용할 값을 변경할 수 있습니다(해당 작업 권한이 있는 경우).
  • OLD의 모든 값은 읽기 전용이며 업데이트할 수 없습니다.


참고: 테이블 자체의 업데이트 작업을 트리거하도록 트리거를 설계한 경우 BEFORE 유형 트리거만 사용할 수 있으며 AFTER 유형 트리거는 허용되지 않습니다.

3) 삭제 트리거

DELETE 문이 실행되기 전이나 후에 응답하는 트리거입니다.

DELETE 트리거를 사용할 때 다음 사항에 주의해야 합니다.

  • DELETE 트리거 코드 내에서 OLD(대소문자 구분 안 함)라는 가상 테이블을 참조하여 삭제된 행에 액세스할 수 있습니다.
  • OLD의 모든 값은 읽기 전용이며 업데이트할 수 없습니다.


일반적으로 MySQL은 트리거 사용 중에 오류를 다음과 같은 방식으로 처리합니다.

트랜잭션 테이블의 경우 트리거가 실패하여 전체 문이 실패하면 해당 문에 의해 수행된 모든 변경 사항이 롤백되고, 비트랜잭션 테이블의 경우 문이 실패하더라도 롤백을 수행할 수 없습니다. 유효하다.

BEFORE 트리거가 실패하면 MySQL은 해당 행에서 작업을 수행하지 않습니다.

BEFORE 또는 AFTER 트리거 실행 중에 오류가 발생하면 해당 트리거를 호출하는 전체 문이 실패합니다.

MySQL은 BEFORE 트리거와 행 작업이 모두 성공적으로 실행된 경우에만 AFTER 트리거를 실행합니다.

MySQL은 트리거를 생성합니다(CREATE TRIGGER)

트리거는 MySQL 데이터 테이블 과 관련된 데이터베이스 개체로   , 정의된 조건이 충족될 때 트리거되고 트리거에 정의된 일련의 명령문을 실행합니다. 이 트리거 기능은 애플리케이션이 데이터베이스 측에서 데이터 무결성을 보장하는 데 도움이 될 수 있습니다.

MySQL 데이터베이스 기본 스킬 전체 실습 icon-default.png?t=N7T8https://edu.csdn.net/course/detail/36210 See More

기본 문법

MySQL 5.7에서는 CREATE TRIGGER 문을 사용하여 트리거를 생성할 수 있습니다.

구문 형식은 다음과 같습니다.

CREATE <触发器名> < BEFORE | AFTER >
<INSERT | UPDATE | DELETE >
ON <表名> FOR EACH Row<触发器主体>

구문은 아래에 설명되어 있습니다.

1) 트리거 이름

트리거의 이름입니다. 트리거는 현재 데이터베이스에서 고유한 이름을 가져야 합니다. 특정 데이터베이스에서 생성하는 경우 이름 앞에 데이터베이스 이름이 와야 합니다.

2) 삽입 | 업데이트 | 삭제

트리거 이벤트는 트리거를 활성화하는 문의 유형을 지정하는 데 사용됩니다.

참고: 세 가지 트리거의 실행 시간은 다음과 같습니다.

  • INSERT: 새 행이 테이블에 삽입되면 트리거가 활성화됩니다. 예를 들어, INSERT의 BEFORE 트리거는 MySQL의 INSERT 문뿐만 아니라 LOAD DATA 문으로도 활성화될 수 있습니다.
  • DELETE: DELETE 및 REPLACE 문과 같이 테이블에서 데이터 행이 삭제되면 트리거가 활성화됩니다.
  • UPDATE: UPDATE 문과 같이 테이블의 데이터 행이 변경되면 트리거가 활성화됩니다.
3) 이전 | 후에

BEFORE 및 AFTER는 트리거가 실행되는 순간 트리거가 실행되는 문 이전에 실행되는지 아니면 실행 후에 실행되는지를 나타냅니다. 새로운 데이터가 조건에 맞는지 확인하려면 BEFORE 옵션을 사용하고, 트리거를 활성화하는 명령문이 실행된 후 여러 개 이상의 변경을 완료하려면 일반적으로 AFTER 옵션을 사용합니다.

4) 테이블 이름

트리거가 연결된 테이블의 이름입니다. 이 테이블은 영구 테이블이어야 합니다. 트리거는 임시 테이블이나 뷰와 연결할 수 없습니다. 테이블에 트리거 이벤트가 발생하면 트리거가 활성화됩니다. 동일한 테이블에는 실행 시간과 이벤트가 동일한 두 개의 트리거가 있을 수 없습니다. 예를 들어, 데이터 테이블의 경우 두 개의 BEFORE UPDATE 트리거가 동시에 있을 수 없지만 BEFORE UPDATE 트리거와 BEFORE INSERT 트리거 또는 BEFORE UPDATE 트리거와 AFTER UPDATE 트리거는 있을 수 있습니다.

5) 트리거 본체

트리거 작업 본문에는 트리거가 활성화될 때 실행될 MySQL 문이 포함되어 있습니다. 여러 문을 실행하려면 BEGIN…END 복합 문 구조를 사용할 수 있습니다.

6) 각 행에 대해

일반적으로 트리거 이벤트의 영향을 받는 각 행에 대해 트리거 동작을 활성화해야 하는 행 수준 트리거링을 나타냅니다. 예를 들어, INSERT 문을 사용하여 여러 데이터 행을 테이블에 삽입하는 경우 트리거는 삽입된 각 데이터 행에 대해 해당 트리거 작업을 수행합니다.

注意:每个表都支持 INSERT、UPDATE 和 DELETE 的 BEFORE 与 AFTER,因此每个表最多支持 6 个触发器。每个表的每个事件每次只允许有一个触发器。单一触发器不能与多个事件或多个表关联。

또한 MySQL에서는 데이터베이스의 기존 트리거를 확인해야 하는 경우 SHOW TRIGGERS 문을 사용할 수 있습니다.

BEFORE 유형 트리거 생성

test_db 데이터베이스에서 tb_emp8 데이터 테이블은 id, name, deptId, 급여 필드를 포함하는 사원 정보 테이블이며, tb_emp8 데이터 테이블의 테이블 구조는 다음과 같다.

mysql> SELECT * FROM tb_emp8;
Empty set (0.07 sec)
mysql> DESC tb_emp8;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(22) | YES  | UNI | NULL    |       |
| deptId | int(11)     | NO   | MUL | NULL    |       |
| salary | float       | YES  |     | 0       |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.05 sec)

[예제 1] SumOfSalary라는 트리거를 생성합니다. 트리거 조건은 tb_emp8 데이터 테이블에 데이터를 삽입하기 전에 새로 삽입된 급여 필드 값을 합산하는 것입니다. 입력 SQL문과 실행과정은 다음과 같다.

mysql> CREATE TRIGGER SumOfSalary
    -> BEFORE INSERT ON tb_emp8
    -> FOR EACH ROW
    -> SET @sum=@sum+NEW.salary;
Query OK, 0 rows affected (0.35 sec)

SumOfSalary 트리거가 생성된 후 tb_emp8 테이블에 레코드가 삽입되면 정의된 합계 값은 아래와 같이 0에서 1500, 즉 삽입된 값 1000과 500의 합계로 변경됩니다.

SET @sum=0;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO tb_emp8
    -> VALUES(1,'A',1,1000),(2,'B',1,500);
Query OK, 2 rows affected (0.09 sec)
Records: 2  Duplicates: 0  Warnings: 0
mysql> SELECT @sum;
+------+
| @sum |
+------+
| 1500 |
+------+
1 row in set (0.03 sec)

AFTER 유형 트리거 생성

test_db 데이터베이스의 데이터 테이블 tb_emp6, tb_emp7은 모두 id, name, deptId, 급여 필드를 포함하는 사원 정보 테이블이며, tb_emp6, tb_emp7 데이터 테이블의 테이블 구조는 다음과 같다.

mysql> SELECT * FROM tb_emp6;
Empty set (0.07 sec)
mysql> SELECT * FROM tb_emp7;
Empty set (0.03 sec)
mysql> DESC tb_emp6;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| deptId | int(11)     | YES  | MUL | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> DESC tb_emp7;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| deptId | int(11)     | YES  |     | NULL    |       |
| salary | float       | YES  |     | 0       |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.04 sec)

[예제 2] double_salary라는 트리거를 생성한다.트리거 조건은 데이터 테이블 tb_emp6에 데이터를 삽입한 후, 데이터 테이블 tb_emp7에도 동일한 데이터가 삽입되고, 급여는 tb_emp6에 새로 삽입된 급여 필드 값의 2가 되는 것이다. 타임스. 입력 SQL문과 실행과정은 다음과 같다.

mysql> CREATE TRIGGER double_salary
    -> AFTER INSERT ON tb_emp6
    -> FOR EACH ROW
    -> INSERT INTO tb_emp7
    -> VALUES (NEW.id,NEW.name,deptId,2*NEW.salary);
Query OK, 0 rows affected (0.25 sec)

double_salary 트리거가 생성된 후 테이블 tb_emp6에 레코드가 삽입되면 아래와 같이 동일한 레코드가 테이블 tb_emp7에도 동시에 삽입되며 급여 필드는 tb_emp6에 있는 급여 필드 값의 2배가 됩니다.

mysql> INSERT INTO tb_emp6
    -> VALUES (1,'A',1,1000),(2,'B',1,500);
Query OK, 2 rows affected (0.09 sec)
Records: 2  Duplicates: 0  Warnings: 0
mysql> SELECT * FROM tb_emp6;
+----+------+--------+--------+
| id | name | deptId | salary |
+----+------+--------+--------+
|  1 | A    |      1 |   1000 |
|  2 | B    |      1 |    500 |
+----+------+--------+--------+
3 rows in set (0.04 sec)
mysql> SELECT * FROM tb_emp7;
+----+------+--------+--------+
| id | name | deptId | salary |
+----+------+--------+--------+
|  1 | A    |      1 |   2000 |
|  2 | B    |      1 |   1000 |
+----+------+--------+--------+
2 rows in set (0.06 sec)

다창 수석 데이터베이스 엔지니어 mysql 데이터베이스 실무 교육 icon-default.png?t=N7T8https://edu.csdn.net/course/detail/39021

추천

출처blog.csdn.net/m0_37449634/article/details/135553488