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

相关推荐
容器( ु⁎ᴗ_ᴗ⁎)ु.。oO20 分钟前
MySQL事务
数据库·mysql
cyt涛2 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油3 小时前
01_SQLite
数据库·sqlite
liuxin334455663 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。3 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec3 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa4 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke4 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D4 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录4 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份