DELETE、TRUNCATE 和 DROP 的区别必须分清
很多人误以为
DROP是“删数据”,其实它删的是表结构本身,连同元数据、索引、触发器、外键约束一并清除。一旦执行,
SELECT都会报错
Table 'xxx' doesn't exist,且无法通过
ROLLBACK恢复(除非在事务中且引擎支持,但 InnoDB 对
DROP TABLE仍会隐式提交)。
DELETE FROM table_name:只删行,保留表结构和索引,可加
WHERE,可回滚
TRUNCATE TABLE table_name:删所有行、重置自增计数器,不可回滚(DDL 操作),不走触发器
DROP TABLE table_name:彻底删除表对象,不可逆,连
SHOW CREATE TABLE都失效
DROP INDEX 在不同存储引擎下的语法差异
MySQL 5.7+ 中,
DROP INDEX不能直接用于主键或唯一约束名;它只认索引名,且必须指定所属表。InnoDB 和 MyISAM 行为一致,但容易因忽略
ON table_name而报错。 正确写法:
DROP INDEX idx_name ON table_name错误写法:
DROP INDEX idx_name(缺少
ON子句,语法错误) 主键不能用
DROP INDEX PRIMARY删除,必须用
ALTER TABLE table_name DROP PRIMARY KEY如果索引是通过
UNIQUE或
FULLTEXT创建的,仍用
DROP INDEX,不区分类型
外键依赖会导致 DROP TABLE 失败
若目标表被其他表的外键引用,
DROP TABLE会直接报错
Cannot delete or update a parent row: a foreign key constraint fails。这不是权限问题,而是 DDL 层级的依赖保护。 先查依赖:
SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'your_table_name';临时禁用检查(仅限调试,生产慎用):
SET FOREIGN_KEY_CHECKS = 0;,执行
DROP后记得恢复
= 1更安全的做法是显式
ALTER TABLE referenced_table DROP FOREIGN KEY fk_name,再删主表 使用
IF EXISTS只能避免“表不存在”报错,对依赖冲突无效:
DROP TABLE IF EXISTS table_name
权限与隐形影响常被忽略
执行
DROP不仅需要
DROP权限,还隐式依赖
CREATE权限(因为 MySQL 内部可能重建内部结构)。另外,
DROP会立即释放磁盘空间,但 InnoDB 表空间文件(如
ibdata1)不一定收缩——除非启用了
innodb_file_per_table=ON且使用独立表空间。 确认权限:
SHOW GRANTS FOR CURRENT_USER;,检查是否含
DROP和
CREATE删除大表时,即使语句秒返回,后台可能仍在清理缓冲池和字典缓存,期间
SHOW PROCESSLIST可能看到
droping table状态 如果表有全文索引,
DROP会同步清理
ft_parse相关缓存,但不会触发分词器重建(因为整个对象已消失) 备份策略必须覆盖
CREATE TABLE语句,否则
DROP后无法靠 binlog 回滚(binlog 记录的是 DDL,不是数据) 真正危险的不是语法写错,而是没意识到
DROP会同时抹掉统计信息、查询计划缓存、以及所有基于该表的视图定义(视图变成无效状态,
SELECT时报错
Table doesn't exist)。
