企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# TRUNCATE ## Name TRUNCATE -- 清空一个或一组表 ## Synopsis ``` TRUNCATE [ TABLE ] [ ONLY ] _name_ [ * ] [, ... ] [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ] ``` ## 描述 `TRUNCATE`快速地从一堆表中删除所有行。它和在每个表上进行无条件的 `DELETE`有同样的效果,不过因为它不做表扫描,因而快得多。另外, 它快速回收磁盘空间,而不是请求一个随后的`VACUUM`操作。 在大表上最有用。 ## 参数 `_name_` 要清空的表名字(可以有模式修饰)。如果在表名前声明了`ONLY`, 那么只有那个表会被清空。如果没有声明`ONLY`,这个表以及其所有子表 (若有)会被清空。可选地,可以在表名后声明`*`以明确指定包括子表。 `RESTART IDENTITY` 截断表中的序列字段的序列值将被重置。 `CONTINUE IDENTITY` 不要改变序列的值。此为缺省。 `CASCADE` 级联清空所有在该表上有外键引用的表,或者由于`CASCADE`而被添加到组中的表。 `RESTRICT` 如果有外键引用数据并且引用表没有在命令行中列出,则拒绝清空。这是缺省。 ## 注意 你必须对表有`TRUNCATE`权限以清空它。 `TRUNCATE`在在操作的每个表上请求一个`ACCESS EXCLUSIVE`锁, 这种锁会阻塞表上的所有其他并发操作。当声明了`RESTART IDENTITY`时, 任何被重启的序列也会被排他锁锁住。如果需要对一个表并发访问, 那么应该使用`DELETE`命令。 如果从其它表有到某个表的外键引用,那么就不能对该表使用`TRUNCATE`, 除非这些表在同一个命令中也被清空。在这种情况下检查有效性要求进行表扫描, 而`TRUNCATE`并不做这样的事情。`CASCADE` 选项可以用于级联包含所有依赖表,但是使用此选项必须十分小心,否则可能丢失原本不想丢失的数据。 `TRUNCATE`不会触发任何在该表上的`ON DELETE`触发器。 但它会触发`ON TRUNCATE`触发器。如果任何表上定义有`ON TRUNCATE` 触发器,则所有的`BEFORE TRUNCATE` 触发器会在任何截断发生之前触发,而所有`AFTER TRUNCATE` 触发器会在最后一个截断执行后和任何序列重设后被触发。该触发器会以表执行的顺序触发 (首先是命令中列出的,然后是任何基于级联添加的)。 | **Warning** | |:--- | | `TRUNCATE`不是mvcc 安全的操作(参考mvcc的文档)。在截断之后,所有并发的事务看到的该表都是空的,即使他们在截断发生前使用快照。 这将是一个针对截断发生之前没有访问截断表的事务的问题,在事务中对截断表的任何访问至少产生一个 `ACCESS SHARE`锁,这将阻塞`TRUNCATE`直到事务完成。 所以截断不会导致在相同表上连续查询时表内容上的明显不一致, 但会导致截断表和数据库中其他表在内容上可见的不一致性。 | `TRUNCATE`在事务中断表数据是安全可的:只要开启的事物不提交,则事物会安全回滚。 当声明了`RESTART IDENTITY`时,隐含的`ALTER SEQUENCE RESTART` 操作也会事务性的完成;也就是,如果包围的事务没有提交,它们将回滚。 这不同于`ALTER SEQUENCE RESTART`的正常行为。要知道, 如果在序列重启之后与事务回滚之前执行了额外的序列操作, 那么这些操作的影响也会回滚,但是它们在`currval()`上的影响不会回滚; 也就是,在事务之后,`currval()`将继续反映在失败事务中获得的最后序列值, 即使序列本身可能与其不再一致。这类似于`currval()`在一个失败事务后的普通行为。 ## 例子 清空`bigtable`和`fattable`表: ``` TRUNCATE bigtable, fattable; ``` 同样地,也重置任何相关的序列生成器: ``` TRUNCATE bigtable, fattable RESTART IDENTITY; ``` 清空`othertable`表,并且级联清空所有通过外键约束引用 `othertable`的表: ``` TRUNCATE othertable CASCADE; ``` ## 兼容性 SQL:2008标准包括一个有语法`TRUNCATE TABLE` `_tablename_` 的`TRUNCATE`命令。`CONTINUE IDENTITY`/`RESTART IDENTITY` 也出现在那个标准中,但是有轻微的不同和相关的含义。该命令的一些并发行为通过标准定义实现的, 所以,如果必要,应该考虑上面的说明并与其他实现比较。