删除表

14
899字 · 3分钟

一、先明确语法差异

1. 语法对比

数据库 TRUNCATE 语法 DELETE 语法(通用)
MySQL TRUNCATE tableName;(table 可省略) DELETE FROM tableName;
Oracle TRUNCATE TABLE tableName;(TABLE 必须写) DELETE FROM tableName;

Oracle 中 TRUNCATE 必须带 TABLE 关键字,而 MySQL 可省略,这是两者最直观的语法区别。

2. 示例验证

  • Oracle 正确写法:truncate table zzwk_11340000002986432d0057_1;
  • MySQL 正确写法:truncate zzwk_11340000002986432d0057_1; 或 truncate table zzwk_11340000002986432d0057_1;(两种都可以)

二、DELETE vs TRUNCATE 核心区别

“高水线”和“自增 ID”:

特性 DELETE(DML) TRUNCATE(DDL)
操作类型 数据操纵语言(DML) 数据定义语言(DDL)
事务性 可回滚(需在事务中执行,未提交前可 rollback) 隐式提交,不可回滚(Oracle/MySQL 均如此)
执行效率 慢(逐行删除,记录日志) 极快(直接清空表,不记录单行日志)
表空间回收 不回收(占用的空间仍保留) 回收(Oracle 直接释放,MySQL InnoDB 也会释放)
高水线(HWM) 不下降(Oracle 中表仍保留原有高水线) 直接重置为 0(高水线下降)
自增 ID(主键) MySQL:继续自增(不会重置);Oracle:需手动重置 MySQL:重置为 1;Oracle:序列需手动重置
触发触发器 会触发 DELETE 触发器 不会触发任何触发器
条件删除 支持 WHERE 子句(可删指定行) 不支持 WHERE(只能清空全表)

关键概念解释(解决你的困惑)

  1. 高水线(HWM)
    可以理解为 Oracle 表的“容量刻度”——比如你往杯子里倒满水,再把水倒掉,杯子的“最高水位线”还在,Oracle 扫描表时仍会扫描到这个高水线位置;而 TRUNCATE 相当于把杯子的“最高水位线”直接擦掉,下次扫描只会从 0 开始,效率大幅提升。

    • DELETE:删完数据后,高水线还在,Oracle 执行 SELECT COUNT(*) 时仍会扫描到原高水线,速度慢;
    • TRUNCATE:高水线重置为 0,SELECT COUNT(*) 瞬间返回 0。
  2. 自增 ID 规则
    • MySQL:
      • DELETE FROM t:自增列(如 id INT AUTO_INCREMENT)继续从最后一次的值自增(比如删前最大 ID 是 100,删后插入新数据 ID 是 101);
      • TRUNCATE TABLE t:自增列直接重置为 1,新插入数据 ID 从 1 开始。
    • Oracle:
      Oracle 本身没有 AUTO_INCREMENT,需用“序列 + 触发器”实现自增:

      • DELETE:序列不会重置(比如序列当前值是 100,删后仍从 101 开始);
      • TRUNCATE:表清空,但序列仍不会自动重置,需手动执行 ALTER SEQUENCE seq_name RESTART WITH 1; 重置。

三、实操注意事项(避坑点)

  1. Oracle 中 TRUNCATE 的权限
    执行 TRUNCATE TABLE 需要表的 DROP 权限(而非 DELETE 权限),如果权限不足会报错,而 DELETE 只需要 DELETE 权限。
  2. MySQL 中 TRUNCATE 的特殊情况
    如果表被外键关联,TRUNCATE 会失败(需先禁用外键约束),而 DELETE 可以正常执行(只要满足外键规则)。
  3. 数据恢复
    • DELETE:未提交时可 ROLLBACK 恢复,提交后可通过日志(如 Oracle 的闪回、MySQL 的 binlog)恢复;
    • TRUNCATE:不可回滚,且日志记录极少,数据几乎无法恢复(生产环境慎用)。

总结

  1. 语法核心:Oracle 的 TRUNCATE 必须写 TABLE 关键字,MySQL 可省略,这是你修正的关键,完全正确;
  2. 核心区别DELETE 是可回滚的 DML(逐行删、不回收空间、高水线不降),TRUNCATE 是不可回滚的 DDL(快速清空、回收空间、高水线重置);
  3. 自增 ID:MySQL 中 TRUNCATE 会重置自增 ID 为 1,DELETE 不会;Oracle 需手动重置序列,两者都不会自动重置。

简单记:清空表且不需要回滚、追求效率 → 用 TRUNCATE;需删指定行、要回滚 → 用 DELETE

本文发布于 24 天前,内容时效性较好
这篇文章对你有帮助吗?