我是关系的初学者,所以这可能听起来很愚蠢。但是,在截断表和删除所有记录之间(在MySQL中)有什么区别(this答案仅表示性能)?
我正在玩(在phpMyAdmin中)我的一个测试表,要检查,如何重置auto_increment
表的值并进入情境,我可以删除所有记录:
DELETE from managers;
但是当我试图截断此表格(TRUNCATE managers
)时,我发出警告:Cannot truncate a table referenced in a foreign key constraint (probes, CONSTRAINT probes_ibfk_4 FOREIGN KEY (manager_id) REFERENCES managers (id));
。
我不得不重置" auto_increment
值为ALTER TABLE managers AUTO_INCREMENT = 1;
。
不是奇怪的事吗?到目前为止,我想,TRUNCATE
= DELETE from managers
(就检查和效果而言,因为性能可能不同,但这不是关键)。
如何在TRUNCATE
上弹出约束警告,但不会在"删除所有"?
答案 0 :(得分:7)
truncate删除所有行后重置auto_increment。所以它与使用DELETE命令删除所有行不同。
TRUNCATE TABLE完全清空表。从逻辑上讲,这是 相当于删除所有行的DELETE语句,但有 在某些情况下存在实际差异。
对于版本5.0.3之前的InnoDB表,InnoDB处理TRUNCATE 通过逐个删除行来表。从MySQL 5.0.3开始,逐行 仅当存在任何FOREIGN KEY约束时才使用删除 参考表格。如果没有FOREIGN KEY约束,InnoDB 通过删除原始表并创建来执行快速截断 一个空的,具有相同的定义,比它快得多 逐个删除行。 (当使用快速截断时,它会重置任何 AUTO_INCREMENT计数器为零。从MySQL 5.0.13开始, 无论如何,AUTO_INCREMENT计数器由TRUNCATE TABLE重置为零 是否存在外键约束。)
在FOREIGN KEY约束引用表的情况下,InnoDB 逐个删除行并处理每个行的约束。如果 FOREIGN KEY约束指定DELETE CASCADE,来自的行 删除子(引用)表,并截断表 空。如果FOREIGN KEY约束没有指定CASCADE,则 TRUNCATE TABLE语句逐个删除行,如果是则停止 遇到子进程引用的父行,返回 这个错误:
错误1451(23000):无法删除或更新父行:异类 键约束失败(
test
。child
,CONSTRAINTchild_ibfk_1
外键(parent_id
)参考parent
(id
))