MyDumper “喜欢” 触发器么?

是的,但现在它更"喜欢"它们,原因如下。

介绍

使用 LIKE 子句过滤特定表中的触发器或视图很常见。但是,它可能会欺骗您,特别是如果您看不到输出(即在非交互式会话中)。让我们看一个简单的例子,以及如何以更可靠的方式处理任务。还有一个指向 mydumper 错误的额外链接,该错误是根据本实验室的调查而修复的。是的,但现在它更喜欢它们,原因如下。

实验室

首先,我们将创建两个只有一个无符号整数列的虚拟表。该列也将是两个表的主键。

sql 复制代码
CREATE TABLE `test_lab` (
`id` int unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `test2lab` (
`id` int unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

我们还将创建第三个表,它将作为我们的"日志"来跟踪前两个表中所做的插入。我们将在这里使用复合主键(表名称和 ID)。

sql 复制代码
CREATE TABLE `log_lab` (
`changed_table` varchar(50) NOT NULL,
`id` int unsigned NOT NULL,
PRIMARY KEY (`changed_table`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

现在,让我们为每个表添加一个触发器。两个表的触发器相同,并将记录复制到日志表。

sql 复制代码
DELIMITER //

CREATE TRIGGER `test_lab_trigger_INS` AFTER INSERT ON `test_lab`

FOR EACH ROW BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END
//

CREATE TRIGGER `test2lab_trigger_INS` AFTER INSERT ON `test2lab`

FOR EACH ROW BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END
//
DELIMITER ;

最后,让我们检查一下我们是否正确完成了所有操作:

sql 复制代码
mysql> insert into `test_lab` values (8) ;
Query OK, 1 row affected (0.00 sec)

mysql> insert into `test2lab` values (2) ;
Query OK, 1 row affected (0.01 sec)

mysql> select * from log_lab ;
+---------------+----+
| changed_table | id |
+---------------+----+
| test_lab      |  8 |
| test2lab      |  2 |
+---------------+----+
2 rows in set (0.00 sec)

现在,我们已准备好运行我们为其创建实验室的测试用例。让我们从使用这个语句开始:

sql 复制代码
mysql> SHOW TRIGGERS LIKE 'test2lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

一张表,一个触发器,一行。都可以。

这次,我们将使用其他表名称:

sql 复制代码
mysql> SHOW TRIGGERS LIKE 'test_lab' ;
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
| test_lab_trigger_INS | INSERT | test_lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
2 rows in set (0.00 sec)

人们可能会惊讶地看到两个表都有两行及其触发器,但这是预期的行为。 LIKE 语句不会根据模式执行严格的比较和过滤。您仍然可以在其中使用通配符 (%),它可以用来代替搜索字符串中任意数量的字符。在 LIKE 语句中使用占位符 () 来匹配任何单个字符的情况不太常见。讽刺的是,我们使用占位符匹配表名称中的""和"2"字符。

在文章的开头,我承诺展示一种更可靠的方法来处理该任务,所以这里是:

sql 复制代码
mysql> SHOW TRIGGERS WHERE `Table` = 'test2lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)

mysql> SHOW TRIGGERS WHERE `Table` = 'test_lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test_lab_trigger_INS | INSERT | test_lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

您可以过滤输出中的任何其他列,不限于表。不要忘记使用 Table,因为它是 MySQL 中的保留字,如果不使用它们(以及大多数其他列名),您将无法逃脱。

如果您想做自己的实验,我将留给读者使用 VIEW 进行相同的测试。

题外话

这时,你可能会问这个极端案例与现实世界有什么关系。当一个包含下划线而另一个包含数字时,表名称略有不同的情况并不常见。除了无法获得您愿意获得的输出之外,这也是 mydumper/myloader 中出现错误的原因,我在此报告:

github.com/mydumper/my...

Mydumper 将每个表的触发器放入单独的文件中,并使用 LIKE 语句导致属于 test2lab 的触发器最终出现在 test_lab 触发器文件中。

结论

本文介绍了了解运算符如何在 LIKE 子句示例中精确执行的重要性、如何创建快速实验室来测试命令的结果以确保结果,以及如何使用运算符替代 LIKE。

更多技术文章,请访问:opensource.actionsky.com/

关于 SQLE

SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。

相关推荐
A XMan.38 分钟前
域名Whois信息查询V2版API接入指南
数据库
heimeiyingwang39 分钟前
【架构实战】可观测性体系:从监控到全链路追踪
网络·数据库·架构
网管NO.143 分钟前
SQL 日期函数全套精讲!时间格式化、日期加减、年月日提取,做日报周报直接套用
数据库·sql
杨云龙UP1 小时前
Linux 根分区被日志吃满?一次 58G Broker 日志清理实战_2026-05-20
linux·运维·服务器·数据库·hdfs·apache
sdk大全1 小时前
Studio 3T for MongoDB 2025.13.0
数据库·mongodb
码农阿豪1 小时前
平替MongoDB:金仓多模数据库助力电子证照国产化实践
数据库·mongodb
罗超驿1 小时前
22.深入剖析JDBC架构:从原生API到企业级数据交互核心
java·数据库·mysql·面试
易辰君1 小时前
【数据库】MongoDB深度解析与Python操作指南:从安装到实战操作全覆盖
数据库·mongodb
一直有一个ac的梦想1 小时前
cmu15445 2025fall lec 18 transactions with two-phase lock
java·开发语言·数据库
身如柳絮随风扬1 小时前
Redis 集群脑裂深度剖析:成因、危害与防丢失策略
数据库