在MySQL数据库的实际使用中,经常会遇到特殊业务场景下的数据转换需求,这类需求如果通过应用层代码处理会增加耦合度,此时使用触发器是更高效的方案。触发器可以在数据发生增删改操作时自动执行预设逻辑,无需额外调用接口即可完成数据转换工作。

什么是MySQL触发器
MySQL触发器是绑定在数据表上的特殊程序,当表发生INSERT、UPDATE、DELETE操作时,会自动触发执行预先定义好的SQL逻辑。触发器的执行是隐式的,不需要外部程序主动调用,非常适合处理数据自动转换、数据校验、操作日志记录等场景。
触发器的触发时机分为两种:
- BEFORE:在数据操作执行之前触发,可用于修改即将写入的数据
- AFTER:在数据操作执行之后触发,可用于基于操作结果做后续处理
特殊业务场景下的数据转换需求
常见的需要触发器处理的特殊业务场景数据转换包括:
- 用户提交的业务数据格式不符合存储规范,需要自动转换为标准格式存储
- 多表关联场景下,主表数据变更后需要自动更新关联表的冗余统计字段
- 敏感数据写入时需要自动做脱敏处理,比如手机号、身份证号的部分字符替换
- 业务编码需要自动转换为对应的中文描述存储到扩展字段中
部署数据转换触发器的完整流程
1. 确认业务需求与触发条件
首先需要明确三个核心要素:触发事件(INSERT/UPDATE/DELETE)、触发时机(BEFORE/AFTER)、需要转换的数据字段和转换规则。比如需求是用户表插入新数据时,自动将手机号中间四位替换为星号存储到脱敏字段中。
2. 编写触发器创建语句
MySQL创建触发器的基础语法如下:
-- 创建触发器语法
CREATE TRIGGER 触发器名称
触发时机 触发事件 ON 表名
FOR EACH ROW
BEGIN
-- 触发器逻辑,NEW代表新数据,OLD代表旧数据
END;
针对上面的手机号脱敏需求,具体创建语句如下:
-- 创建用户表插入前的触发器,处理手机号脱敏
DELIMITER //
CREATE TRIGGER tr_user_phone_mask
BEFORE INSERT ON user_info
FOR EACH ROW
BEGIN
-- 判断手机号不为空时做脱敏处理
IF NEW.phone IS NOT NULL AND CHAR_LENGTH(NEW.phone) = 11 THEN
-- 将手机号中间四位替换为****
SET NEW.phone_mask = CONCAT(LEFT(NEW.phone, 3), '****', RIGHT(NEW.phone, 4));
ELSE
SET NEW.phone_mask = NEW.phone;
END IF;
END //
DELIMITER ;
3. 验证触发器功能
创建完成后可以插入测试数据验证触发器是否生效:
-- 插入测试用户数据
INSERT INTO user_info (user_name, phone) VALUES ('张三', '13812345678');
-- 查询插入结果,查看phone_mask字段是否符合预期
SELECT user_name, phone, phone_mask FROM user_info WHERE user_name = '张三';
执行后可以看到phone_mask字段的值为138****5678,说明触发器已经正常执行数据转换。
复杂场景的数据转换触发器示例
再举一个业务编码转换的场景,假设业务表存储的是商品类型编码,需要自动将编码对应的中文名称存储到type_name字段中:
-- 创建商品表更新时的触发器,处理类型编码转中文
DELIMITER //
CREATE TRIGGER tr_goods_type_convert
BEFORE UPDATE ON goods_info
FOR EACH ROW
BEGIN
-- 定义变量存储类型名称
DECLARE v_type_name VARCHAR(20);
-- 根据编码获取对应的中文名称
IF NEW.goods_type_code = '01' THEN
SET v_type_name = '电子产品';
ELSEIF NEW.goods_type_code = '02' THEN
SET v_type_name = '家居用品';
ELSEIF NEW.goods_type_code = '03' THEN
SET v_type_name = '食品饮料';
ELSE
SET v_type_name = '其他';
END IF;
-- 设置转换后的类型名称
SET NEW.type_name = v_type_name;
END //
DELIMITER ;
部署触发器的注意事项
- 触发器逻辑尽量简洁,避免复杂查询和循环,否则会影响数据操作的性能
- BEFORE触发器如果修改了NEW的值,最终写入数据库的是修改后的值;AFTER触发器不能修改NEW的值
- 同一个表同一个触发事件同一个时机只能创建一个触发器,重复创建会报错
- 触发器执行出错会导致原数据操作也失败,需要做好异常处理逻辑的测试
- 如果业务转换逻辑后续可能频繁变动,不建议使用触发器,避免维护成本过高
触发器的查看与删除
如果需要查看已创建的触发器,可以使用以下语句:
-- 查看当前数据库所有触发器 SHOW TRIGGERS; -- 查看指定触发器的定义 SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = 'tr_user_phone_mask';
如果不再需要某个触发器,可以使用删除语句:
-- 删除指定触发器 DROP TRIGGER IF EXISTS tr_user_phone_mask;