“TRUNCATE 不运行 ON DELETE 触发器” true 或 false

gee*_*sal 5 mysql trigger truncate ddl mysql-5.0

我正在搜索为什么 TRUNCATE 被放置在 DDL 而不是 DML 中的主题,我在这里找到了以下答案 Why is truncate DDL?

我这个答案我发现了一个句子如下

“TRUNCATE 不运行 ON DELETE 触发器这一事实也使其与正常的 DML 操作区分开来”

这与MYSQL 参考手册相冲突,其中说

“如果 FOREIGN KEY 约束指定 DELETE CASCADE,则子(引用)表中的行将被删除,并且截断的表将变为空。”

我正处于一种迷茫的状态。请详细说明这个问题。

谢谢

ype*_*eᵀᴹ 4

您的第一个链接(为什么是 truncate DDL?)是关于 Oracle,而不是 MySQL。虽然相关,但不同的 DBMS 以不同的方式实现相同的功能。在Oracle和SQL Server中TRUNCATE是DDL,而不是DML。

在 MySQL 中,使用哪个版本很重要:

从逻辑上讲,TRUNCATE TABLE相当于删除所有行语句DELETE,但在某些情况下存在实际差异

对于 InnoDB 表:

  • 如果没有FOREIGN KEY约束,InnoDB会通过删除原始表并创建一个具有相同定义的空表来执行快速截断,这比逐行删除要快得多。

  • 当您在启用该innodb_file_per_table选项的情况下使用这种快速截断技术时,操作系统可以重用释放的磁盘空间。对于 InnoDB 插件的用户,空间会自动回收,如使用 回收磁盘空间中所述TRUNCATE TABLE。如果您没有安装 InnoDB 插件,请发出该OPTIMIZE TABLE语句来释放表的磁盘空间。

  • 如果存在任何引用该表的FOREIGN KEY约束,InnoDB 会TRUNCATE TABLE通过逐行删除行来处理,并在处理过程中处理约束。如果FOREIGN KEY约束指定DELETE CASCADE,则子(引用)表中的行将被删除,并且截断的表将变为空。如果FOREIGN KEY约束未指定CASCADE,则该TRUNCATE TABLE语句将逐行删除行,并在遇到子行引用的父行时停止,返回以下错误:

    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign  
    key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1`  
    FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))  
    
    Run Code Online (Sandbox Code Playgroud)

对于5.5 及更高版本,文档说:

从逻辑上讲,TRUNCATE TABLE类似于删除所有行语句DELETE,或一系列DROP TABLEandCREATE TABLE语句。为了获得高性能,它绕过了删除数据的DML方法。因此,它无法回滚不会导致ON DELETE触发器触发,并且无法对具有父子外键关系的 InnoDB 表执行

虽然TRUNCATE TABLE与 类似DELETE,但它被归类为 DDL 语句而不是 DML 语句。与MySQL 5.5有DELETE以下不同:

...