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
也出现在那个标准中,但是有轻微的不同和相关的含义。该命令的一些并发行为通过标准定义实现的, 所以,如果必要,应该考虑上面的说明并与其他实现比较。