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 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。

相关推荐
devmoon2 小时前
在 Polkadot Runtime 中添加多个 Pallet 实例实战指南
java·开发语言·数据库·web3·区块链·波卡
认真的薛薛3 小时前
数据库-sql语句
数据库·sql·oracle
爱学英语的程序员3 小时前
面试官:你了解过哪些数据库?
java·数据库·spring boot·sql·mysql·mybatis
·云扬·4 小时前
MySQL Redo Log落盘机制深度解析
数据库·mysql
用户982863025684 小时前
pg内核实现细节
数据库
飞升不如收破烂~4 小时前
Redis 分布式锁+接口幂等性使用+当下流行的限流方案「落地实操」+用户连续点击两下按钮的解决方案自用总结
数据库·redis·分布式
workflower4 小时前
业务需求-假设场景
java·数据库·测试用例·集成测试·需求分析·模块测试·软件需求
亓才孓4 小时前
[JDBC]基于三层架构和MVC架构的JDBCTools
数据库
IT邦德5 小时前
RPM包快速安装Oracle26ai
数据库·oracle
Dovis(誓平步青云)5 小时前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法