Skip to content

TRUNCATE TABLE 命令

PostgreSQL 的 TRUNCATE TABLE 命令用于快速删除表或一组表中的所有行。它在功能上类似于对每个表执行不带 WHERE 子句的 DELETE 命令,但 TRUNCATE 对于大型表来说明显更快、更高效。

与 DELETE 的主要区别:

  • 性能: TRUNCATE 不会逐行扫描表,因此速度快得多。
  • 资源使用: 它会立即回收磁盘空间,而 DELETE 需要后续的 VACUUM 操作才能回收。
  • 触发器: TRUNCATE 不会触发为表定义的任何 ON DELETE 触发器。
  • 事务: 它是事务安全的。如果 TRUNCATE 语句是事务的一部分,您可以回滚它。

重要的是不要将 TRUNCATE 与 DROP TABLE 混淆。TRUNCATE 仅删除数据,而保留表结构完整。DROP TABLE 则完全删除表定义、其数据以及所有相关的索引和约束。

TRUNCATE TABLE 的基本语法如下:

TRUNCATE TABLE table_name [ , ... ] [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ];

可选子句:

  • table_name [ , ... ]:您可以通过提供逗号分隔的列表一次性截断多个表。
  • RESTART IDENTITY:自动重新启动与被截断表列(例如,来自 SERIAL 或 IDENTITY 列)绑定的任何序列。下一个插入的行将从序列的初始值开始。这是默认且最常见的行为。
  • CONTINUE IDENTITY:不更改任何序列的值。下一个插入的行将使用序列中的下一个值,如同没有发生截断一样。
  • CASCADE:自动截断所有对指定表具有外键引用的表。
  • RESTRICT:如果任何其他表对指定表具有外键引用,则阻止截断。这是默认行为。

让我们使用上一个示例中的 employees 表,该表有一个 BIGSERIAL 主键(id)。

-- 假设 employees 表有几条记录:
SELECT id, full_name FROM employees;
id | full_name
----+------------------
1 | Alice Wonderland
2 | Bob Builder
3 | Charlie Chaplin
(3 rows)

现在,让我们截断这个表。以下命令将删除所有行并重置 id 序列。

testdb=# TRUNCATE TABLE employees RESTART IDENTITY;
TRUNCATE TABLE

该表现在为空。一个 SELECT 查询证实了这一点:

testdb=# SELECT * FROM employees;
id | full_name | age | department | salary | hire_date
----+-----------+-----+------------+--------+-----------
(0 rows)

因为我们使用了 RESTART IDENTITY,所以我们插入的下一条记录的 id 将是 1。

testdb=# INSERT INTO employees (full_name, age, department, salary)
VALUES ('Frank N. Stein', 40, 'R&D', 150000.00) RETURNING id;
id
----
1
(1 row)