编程数据库工程师

描述 SQL 中安全删除/清除数据 (DELETE, TRUNCATE) 的过程和特点。它们之间的区别是什么,事务、锁定和触发器的限制是什么,以及如何避免意外丢失数据?

用 Hintsage AI 助手通过面试

答案

DELETETRUNCATE — 都是清除表格的工具,但工作方式不同:

  • DELETE 根据条件删除行或删除所有行,支持 WHERE,可以回滚,激活触发器。在大量行(逐行)时可能会慢。
  • TRUNCATE 立即清空整个表,无法使用 WHERE,通常不逐行记录日志,并不总是激活触发器。在大多数情况下,操作是不可逆的,在某些数据库中无法回滚。

细微差别:

  • DELETE 支持事务回滚 (ROLLBACK),TRUNCATE — 不支持或取决于数据库。
  • TRUNCATE 通常会重置身份/序列计数器。
  • 如果有外键或对表的引用,则无法使用 TRUNCATE。

示例:

-- 删除创建超过3年的订单 DELETE FROM orders WHERE created_at < CURRENT_DATE - INTERVAL '3 years'; -- 完全清空表(快速) TRUNCATE TABLE logs;

误导性问题

可以在 TRUNCATE 后恢复数据吗?

常见错误:认为可以像 DELETE 一样,通过事务回滚 TRUNCATE。但 TRUNCATE 通常不可回滚或执行 UNDO,除了一些特定的数据库(例如,在事务内的 PostgreSQL)

示例(在大多数数据库中):

BEGIN; TRUNCATE TABLE orders; ROLLBACK; -- 在大多数数据库中不起作用,数据丢失!

因为不了解主题细节而导致的实际错误示例


故事

在生产数据库中使用 TRUNCATE 删除临时数据,而不是使用 TEST。删除行的审核触发器仅在 DELETE 上触发 — 关于丢失数据、时间和用户的信息缺失。导致事件调查受到影响。


故事

在存在外键的情况下使用 TRUNCATE 清空表。SQL 因引用完整性约束而抛出错误,脚本未完成,自动化停止。解决方案:暂时移除外键或使用 DELETE。


故事

在大表中通过 DELETE 进行大规模删除数据而不进行批处理:由于长时间的锁定,数据库"挂起",其他事务等待释放锁。结果 - 系统停机。正确的做法:如果支持,使用 DELETE LIMIT/OFFSET,或进行批处理。