数据库原理学习——MySql触发器详解

news2024/12/23 3:41:58

目录

一、什么是触发器(Trigger)?

二、触发器的特点

三、MySQL中触发器的用法、语法

1. 定义触发器  2. 触发器逻辑开始

3. 触发条件检查  4. 删除逻辑

5. 结束逻辑  6. DELIMITER 语句

四、示例演示触发器的执行过程

五、触发器的应用场景(六种场景,含示例代码)

补充:触发器如何关闭

总结


一、什么是触发器(Trigger)?

触发器(Trigger)是数据库中的一种特殊存储程序,它绑定到某张表(或视图)上,并在特定的数据库操作(如 INSERTUPDATEDELETE)发生时自动执行预定义的操作。触发器无需手动调用,是一种事件驱动的机制。

二、触发器的特点

  1. 自动执行:一旦满足触发条件,触发器会在相关操作执行之前或之后自动运行。

  2. 绑定表:每个触发器都与特定的表绑定,只对该表的操作有效。

  3. 操作类型:常见触发器类型包括:

    • AFTER DELETE在删除数据之后执行。

    • BEFORE DELETE在删除数据之前执行。

    • AFTER UPDATE在更新数据之后执行。

    • BEFORE UPDATE:在更新数据之前执行。

    • AFTER INSERT在插入数据之后执行。

    • BEFORE INSERT在插入数据之前执行。

  4. 适用范围

    • 触发器作用于每一行操作(FOR EACH ROW),或是整个语句的操作(FOR EACH STATEMENT,但在 MySQL 中不支持)。


三、MySQL中触发器的用法、语法

下面是一个用于清理数据的触发器代码示例,为了使大家更好的理解触发器的使用,下面将为大家逐帧分析每句代码的作用以及使用方法。

(题目:在社区表community中,当新增新的小区时;触发事件为当前新增小区这个insert操作,条件是:新增小区楼栋数量 大于20栋 且 住户不低于150人,若满足条件则:在访客记录表manual_record中查询当前所有已离开的访客记录,将离开时间(out_time)距离现在已经是一年以前的记录都删除; )

DELIMITER $$
​
CREATE TRIGGER update_is_leave_cleanup
AFTER INSERT ON community
FOR EACH ROW
BEGIN
  -- 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人
  IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN
    -- 删除所有离开时间超过一年的访客记录
    DELETE FROM manual_record
    WHERE is_leave = 1
      AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
  END IF;
END$$
​
DELIMITER ;

这段代码定义了一个 MySQL 触发器,用于在对表 community执行 insert操作后自动执行特定逻辑。以下是逐步的解释:

1. 定义触发器
CREATE TRIGGER update_is_leave_cleanup
AFTER INSERTON community
FOR EACH ROW
  • CREATE TRIGGER update_is_leave_cleanup:创建一个名为 update_is_leave_cleanup 的触发器。

  • AFTER INSERT:表示在 community表执行 INSERT操作后触发该触发器。

  • ON community:触发器绑定到 community表。

  • FOR EACH ROW:触发器对 UPDATE 操作的每一行都生效(逐行触发)。


2. 触发器逻辑开始
BEGIN
...
end
  • BEGINEND 标志触发器主体,表示触发器的逻辑操作。


3. 触发条件检查
 -- 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人
  IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN
  • NEW.字段名:表示插入的新值。

  • 条件含义:

    • 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人。

    • 如果 NEW.term_count > 20 且 NEW.per_count >= 150,说明当前新增记录符合条件。

2. OLD.字段名的补充:

  • OLD 是在 DELETEUPDATE 触发器中使用的,用于引用被修改或删除的 旧数据
  • INSERT 触发器中,OLD 不可用,因为没有“旧数据”。
触发器类型NEWOLD
BEFORE INSERT可用(可修改)不可用
AFTER INSERT可用(只读)不可用
BEFORE UPDATE可用(可修改)可用(只读)
AFTER UPDATE可用(只读)可用(只读)
BEFORE DELETE不可用可用(只读)
AFTER DELETE不可用可用(只读)

4. 删除逻辑
DELETE FROM manual_record
WHERE is_leave = 1
  AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
  • DELETE FROM manual_record:删除符合条件的记录。

条件 1:is_leave = 1

  • 仅删除已经离开的记录。

条件 2:out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR)

  • out_time 是记录的离开时间。

  • DATE_SUB(NOW(), INTERVAL 1 YEAR) 计算当前时间减去 1 年的日期。

  • 如果 out_time 早于一年前,则认为该记录已过期,删除之。


5. 结束逻辑
END IF;
END$$
  • END IF;:结束条件语句。

  • END$$:标志触发器逻辑结束。


6. DELIMITER 语句
DELIMITER $$
  • 默认的 MySQL 语句分隔符是 ;

  • 在创建触发器时,为了避免触发器内部的 ; 与默认分隔符冲突,使用 DELIMITER 改变分隔符(如 $$)。

  • DELIMITER ;:在触发器定义完成后,将分隔符改回默认值。

7.功能总结
  • 触发器目标

    1. 检查新增小区是否满足指定条件。

    2. 删除manual_record表中所有满足以下条件的记录:

      ①is_leave = 1(表示访客已离开)。
      ②out_time 距离当前时间已有 1 年以前。
  • 触发时机: 每当 community表中新增(楼栋数量大于20且住户不低于150人的)小区时,该触发器会自动执行。

四、示例演示触发器的执行过程

以下步骤将演示如何使用上述触发器。

1. 表结构准备

创建触发器涉及到两张表:communitymanual_record。我们先定义表结构:

community
CREATE TABLE 
community ( 
    id INT AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255), term_count INT, -- 楼栋数量 
    per_count INT -- 住户数量 
);
manual_record
CREATE TABLE 
manual_record ( 
    id INT AUTO_INCREMENT PRIMARY KEY, 
    is_leave TINYINT(1), -- 是否离开 (1: 已离开, 0: 未离开) 
    out_time DATETIME -- 离开时间 
);
2. 插入数据

在触发器触发前,我们需要确保 manual_record 表中有符合条件的数据:

manual_record 表插入数据
INSERT INTO manual_record (is_leave, out_time) 
VALUES (1, '2022-12-01 12:00:00'), -- 超过一年的离开记录 
(1, '2023-06-01 12:00:00'), -- 未超过一年的离开记录 
(0, '2023-12-01 12:00:00'); -- 未离开的记录
查看 manual_record 表内容
SELECT * FROM manual_record;

结果:

idis_leaveout_time
112022-12-01 12:00:00
212023-06-01 12:00:00
302023-12-01 12:00:00
3. 触发器测试
community 表插入满足条件的记录

触发器的条件是 term_count > 20per_count >= 150。执行以下插入语句:

INSERT INTO community (name, term_count, per_count) 
VALUES ('Example Community', 25, 200);
检查触发器执行结果

触发器应该已经被触发,并从 manual_record 表中删除所有离开时间超过一年的记录。

SELECT * FROM manual_record;

结果:

idis_leaveout_time
212023-06-01 12:00:00
302023-12-01 12:00:00

解释

  • ID 为 1 的记录已被删除,因为它的离开时间(2022-12-01)超过了一年。
  • ID 为 23 的记录未被删除,因为它们不满足删除条件。

4. 插入不满足条件的记录

验证触发器不会在条件不满足时执行:

INSERT INTO community (name, term_count, per_count)
 VALUES ('Small Community', 15, 100);

再次检查 manual_record 表,结果没有变化,仍为:

idis_leaveout_time
212023-06-01 12:00:00
302023-12-01 12:00:00

解释: 触发器未触发,因为 term_count = 15per_count = 100 不满足条件。


注意事项

  1. 触发器性能:如果表数据量大,触发器中执行 DELETE 操作可能会影响性能。

  2. 事务支持:如果 UPDATE 操作失败,触发器逻辑也不会执行。

  3. 调试触发器:可以通过启用 MySQL 日志或手动检查数据变化来调试触发器。

  4. 数据备份:删除记录操作是不可逆的,在执行触发器前确保数据已备份。

如有其他问题,可以进一步优化触发器逻辑! 😊

 五、触发器的应用场景

以下是六个适合使用触发器的实际项目场景,包含基础代码;

1. 数据完整性和一致性
  • 确保数据满足特定的业务规则,避免人为错误。

  • 触发器代码示例①:在用户表插入新记录时,自动设置默认值或校验数据合法性。

    CREATE TRIGGER set_default_role
    BEFORE INSERT ON users
    FOR EACH ROW
    BEGIN
      IF NEW.role IS NULL THEN
        SET NEW.role = 'user';
      END IF;
    END;

2. 自动审计(Audit Log)
  • 自动记录对表的增删改操作,追踪数据变化历史。

  • 触发器代码示例②:在修改数据时,记录操作日志。

    CREATE TRIGGER log_updates
    AFTER UPDATE ON employees
    FOR EACH ROW
    BEGIN
      INSERT INTO audit_log (table_name, action, old_value, new_value, change_time)
      VALUES ('employees', 'UPDATE', OLD.salary, NEW.salary, NOW());
    END;

3. 级联操作
  • 自动处理与主表相关的其他表数据,以保持数据一致性。

  • 触发器代码示例③:在删除订单时,同时删除与该订单相关的所有明细记录。

    CREATE TRIGGER cascade_delete_order
    AFTER DELETE ON orders
    FOR EACH ROW
    BEGIN
      DELETE FROM order_details WHERE order_id = OLD.id;
    END;

4. 定期清理数据
  • 对过期或冗余的数据进行自动清理。

  • 触发器代码示例④:当用户状态更新为注销时,自动清理其关联的会话数据。

    CREATE TRIGGER cleanup_sessions
    AFTER UPDATE ON users
    FOR EACH ROW
    BEGIN
      IF NEW.status = 'deactivated' THEN
        DELETE FROM sessions WHERE user_id = NEW.id;
      END IF;
    END;

5. 复杂计算或衍生数据更新
  • 根据某些操作自动更新相关的统计信息或衍生数据。

  • 触发器代码示例⑤:当订单状态更新时,重新计算用户累计消费金额。

    CREATE TRIGGER recalculate_total_spent
    AFTER UPDATE ON orders
    FOR EACH ROW
    BEGIN
      UPDATE customers
      SET total_spent = (SELECT SUM(total_price) FROM orders WHERE customer_id = NEW.customer_id)
      WHERE id = NEW.customer_id;
    END;

6. 安全控制
  • 限制对敏感数据的非法修改或记录潜在违规行为。

  • 触发器代码示例⑥:防止员工工资被修改为负值。

    CREATE TRIGGER prevent_negative_salary
    BEFORE UPDATE ON employees
    FOR EACH ROW
    BEGIN
      IF NEW.salary < 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary cannot be negative';
      END IF;
    END;

六、触发器的优缺点

优点:
  1. 自动化:无需手动触发或调用,减少代码冗余。

  2. 提高数据一致性:通过预定义规则,确保数据满足业务逻辑。

  3. 分离业务逻辑:将部分逻辑从应用程序移到数据库,集中管理。

  4. 安全性增强:可以避免应用层的意外或恶意操作。

缺点:
  1. 调试困难:触发器是隐式执行的,不易定位问题。

  2. 性能开销:复杂的触发器逻辑可能对数据库性能造成影响,尤其是高并发场景。

  3. 不可移植性:触发器依赖于特定数据库的实现,迁移到其他数据库可能需要重写。

  4. 隐藏逻辑:触发器的自动执行特性可能让开发人员忽略其作用,导致意外行为。

补充:触发器如何关闭

在 MySQL 中,可以通过以下两种方法关闭触发器:


1. 禁用触发器

  • 可以使用命令临时禁用触发器,以停止触发器的执行,而无需删除触发器定义。
  • 需要注意的是,MySQL 不支持直接禁用单个触发器,但可以通过禁用整个表的触发器来达到类似的效果。
禁用所有触发器(全局禁用)
SET GLOBAL DISABLE_TRIGGERS = 1;
启用所有触发器(全局启用)
SET GLOBAL DISABLE_TRIGGERS = 0;

2. 删除触发器

如果需要永久关闭某个触发器,可以直接使用 DROP TRIGGER 命令删除触发器。

删除触发器的语法
DROP TRIGGER [IF EXISTS] trigger_name;
示例

假设有一个触发器 名称为:update_is_leave_cleanup,可以用以下命令删除:

DROP TRIGGER IF EXISTS update_is_leave_cleanup;

3. 触发器删除注意事项

  1. 作用范围:触发器是绑定在特定表上的,删除触发器只会影响当前表,不会影响其他表。

  2. 权限要求:删除触发器需要具有 SUPERTRIGGER 权限。

  3. 无法撤销:删除触发器是永久操作,触发器的定义不会被保存,因此建议在删除之前备份触发器定义。


4. 示例:完整操作流程

(1)查看现有触发器

可以查询数据库中的触发器列表,确认需要删除的触发器名称。

SHOW TRIGGERS;
(2)删除触发器
DROP TRIGGER IF EXISTS update_is_leave_cleanup;
(3)验证触发器是否已被删除

重新查询触发器列表,确认是否已经删除:

SHOW TRIGGERS;

触发器的使用建议:

  • 临时关闭触发器:建议尽量避免直接删除触发器,尤其是在调试或临时停用的情况下,可以通过全局禁用的方式实现。
  • 备份触发器:如果确实需要删除触发器,请提前备份触发器的定义,以便未来需要时快速恢复。

触发器的备份示例:

SHOW CREATE TRIGGER update_is_leave_cleanup \G;

此命令会显示触发器的创建语句,可以复制并保存以备后续使用。


总结

        触发器是一种强大的工具,用于增强数据库的自动化处理能力。它适合处理诸如数据校验、审计记录、自动清理、级联操作等任务,但应谨慎使用,避免复杂逻辑影响性能。如果业务需求涉及复杂逻辑,建议将部分逻辑移到应用程序中实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型微调---Lora微调实战

目录 一、前言二、LoRA实战2.1、下载模型到本地2.2、加载模型与数据集2.3、处理数据2.4、LoRA微调2.5、训练参数配置2.6、开始训练 三、模型评估四、完整训练代码 一、前言 LoRA是一种参数高效的微调技术&#xff0c;通过低秩转换对大型语言模型进行适应性更新&#xff0c;减少…

centos7下docker 容器实现redis主从同步

1.下载redis 镜像 docker pull bitnami/redis2. 文件夹授权 此文件夹是 你自己映射到宿主机上的挂载目录 chmod 777 /app/rd13.创建docker网络 docker network create mynet4.运行docker 镜像 安装redis的master -e 是设置环境变量值 docker run -d -p 6379:6379 \ -v /a…

SLAAC如何工作?

SLAAC如何工作&#xff1f; IPv6无状态地址自动配置(SLAAC)-常见问题 - 苍然满关中 - 博客园 https://support.huawei.com/enterprise/zh/doc/EDOC1100323788?sectionj00shttps://www.zhihu.com/question/6691553243/answer/57023796400 主机在启动或接口UP后&#xff0c;发…

2024.12.21辩论赛感受

背景 今天辩论赛的双方论点是&#xff1a; 正方&#xff1a;寒假留在研发中心的收获大 反方&#xff1a;寒假去做其他事情的收获 辩论赛&#xff0c;为了锻炼自己&#xff0c;选择了不想选择以及相对不好辩论的反方。出现的状况有一下几点&#xff1a; 1.发现自己脑子完全跟不…

【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类

文章目录 一、this扩展方法1、扩展方法的基本语法2、使用扩展方法3、扩展方法的注意事项5、扩展方法的限制6、总结 二、运算符重载1、C# 运算符重载2、运算符重载的基本语法3. 示例&#xff1a;重载加法运算符 ()4、使用重载的运算符5、支持重载的运算符6、不能重载的运算符7、…

C语言:文件IO

C语言&#xff1a;文件IO 文件操作 概述 什么是文件 文件是保存在外存储器&#xff08;一般代指磁盘&#xff0c;U盘&#xff0c;移动硬盘等&#xff09;的数据的集合 文件操作体现在哪几个方面 文件内容的读取文件内容的写入 数据的读取和写入可被视为针对文件进行输入&…

时间序列异常值处理方法

文章目录 一、删除法二、替换法三、插值法四、滑动窗口五、基于模型的替换 时间序列相关参考文章&#xff1a; 时间序列预测算法—ARIMA 时间序列预测算法—Prophet 时间序列分类任务—tsfresh python时间序列处理 有季节效应的非平稳序列分析 时间序列异常值检测方法 时间序列…

【报错】node:internal/modules/cjs/loader:936

报错问题&#xff1a; 当执行npm run dev后&#xff0c;出现下面错误 这个错误一般是由于Node.js无法找到所需的模块而引起的&#xff0c;解决此问题的一种方法就是重新安装所需的模块。 解决办法&#xff1a; 删除npm install 所下载在项目里的node_modules文件执行操作&…

故障诊断 | 一个小创新:特征提取+KAN分类

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 基于FFT CNN - BiGRU-Attention 时域、频域特征注意力融合的轴承故障识别模型-CSDN博客 基于FFT CNN - Transformer 时域、频域特征融合的轴承故障识别模型-CSDN博客 P…

javac 编译java文件源码 怎么生成 ast语法树 步骤详解

在 javac 中&#xff0c;编译源代码并生成抽象语法树&#xff08;AST&#xff09;是一个多步骤的过程&#xff0c;涉及从源码解析到最终生成字节码。以下是详细步骤&#xff0c;描述了如何使用 javac 编译源码并生成 AST。 1. 准备源文件 javac 首先需要源文件。这些源文件是…

人工智能入门是先看西瓜书还是先看花书?

在人工智能入门时&#xff0c;关于先看《机器学习》&#xff08;西瓜书&#xff09;还是先看《深度学习》&#xff08;花书&#xff09;的问题&#xff0c;实际上取决于个人的学习目标和背景。 《机器学习》&#xff08;西瓜书&#xff09;由周志华教授撰写&#xff0c;是一本…

Linux 安装Nginx 并配置启动 (已实测)

文章目录 一、安装Nginx二、配置 Nginx 为系统服务 一、安装Nginx 安装依赖&#xff0c;确保Nginx编译和运行正常&#xff0c;打开终端执行以下命令 yum install -y wget gcc-c pcre-devel zlib-devel openssl-devel下载Nginx # 例如&#xff0c;下载Nginx 1.24.0版本 wget …

Linux 下的 GPT 和 MBR 分区表详解

文章目录 Linux 下的 GPT 和 MBR 分区表详解一、分区表的作用二、MBR&#xff08;Master Boot Record&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 三、GPT&#xff08;GUID Partition Table&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 四…

10. 虚拟机VMware Workstation Pro下共享Ubuntu和Win11文件夹

本文记录当前最新版虚拟机VMware Workstation Pro&#xff08;2024.12&#xff09;如何在win11下共享文件&#xff0c;以实现Windows与Ubuntu互传文件的目的。 1. 创建共享文件夹 1.1 先关闭虚拟机的客户机&#xff0c;打开虚拟机设置 1.2 在虚拟机设置界面找到“选项”->“…

有哪些免费的 ERP 软件可供选择?哪些 ERP 软件使用体验较好?

想找个 “免费” 的 ERP 软件&#xff1f; 咱得知道&#xff0c;ERP 那可是涉及财务、人力、供应链、采购、销售等好多方面的重要企业软件。功能这么全&#xff0c;能免费才怪呢&#xff01;真要是有免费的&#xff0c;早就火遍大江南北&#xff0c;说不定把市场都垄断了&…

2024 年的科技趋势

2024 年在科技领域有着诸多重大进展与突破。从人工智能、量子计算到基因组医学、可再生能源以及新兴技术重塑了众多行业。随着元宇宙等趋势的兴起以及太空探索取得的进步&#xff0c;未来在接下来的岁月里有望继续取得进展与突破。让我们来探讨一下定义 2024 年的一些关键趋势&…

python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django

windows首先安装rabbitmq 点击参考安装 1、环境介绍 Python 3.10.16 其他通过pip安装的版本(Django、pika、celery这几个必须要有最好版本一致) amqp 5.3.1 asgiref 3.8.1 async-timeout 5.0.1 billiard 4.2.1 celery 5.4.0 …

厦门凯酷全科技有限公司短视频带货可靠吗?

在当今这个数字化时代&#xff0c;抖音作为短视频和直播带货的领军平台&#xff0c;已经吸引了无数商家的目光。而在这一片繁荣的电商蓝海中&#xff0c;厦门凯酷全科技有限公司&#xff08;以下简称“凯酷全”&#xff09;凭借其专业的团队、丰富的经验和创新的服务模式&#…

从源码分析swift GCD_DispatchGroup

前言&#xff1a; 最近在写需求的时候用到了DispatchGroup&#xff0c;一直没有深入去学习&#xff0c;既然遇到了那么就总结下吧。。。。 基本介绍&#xff1a; 任务组&#xff08;DispatchGroup&#xff09; DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…

在C#中使用资源保存图像和文本和其他数据并在运行时加载

资源是您可以构建到应用程序中的图像、字符串、文本文件和其他数据。您的程序可以在运行时加载资源以显示新图片、文本或其他内容。 要将资源添加到项目&#xff0c;请打开“项目”菜单并选择最底部的“属性”命令。在“属性”页面上&#xff0c;单击“资源”选项卡。现在&…