PostgreSQL 删除所有内容

247

你好,我想删除postgresql表中的所有数据,但不删除表本身。如何实现?


1
可能是 在 Postgres 数据库中截断所有表 的重复问题。 - Craig Ringer
5个回答

263

8
谢谢!这就是我找到的信息:https://dev59.com/83E85IYBdhLWcg3wVR6g - vo1d

210

在PostgreSQL数据库中可以通过多种方式删除表格的内容。

使用SQL删除表格内容:

删除单个表格的内容:

TRUNCATE table_name;
DELETE FROM table_name;

删除所有命名表中的内容:

TRUNCATE table_a, table_b, …, table_z;

删除具有名称的表及引用它们的表(稍后我将在本答案中详细解释)的内容:

TRUNCATE table_a, table_b CASCADE;

使用pgAdmin删除表格内容:

删除一个表格的内容:

Right click on the table -> Truncate

删除表的内容以及引用该表的其他表:

Right click on the table -> Truncate Cascaded

delete和truncate的区别:

根据文档:

DELETE从指定的表中删除满足WHERE子句的行。如果WHERE子句不存在,则其效果是删除表中的所有行。 http://www.postgresql.org/docs/9.3/static/sql-delete.html

TRUNCATE是PostgreSQL的扩展功能,提供了一种更快的机制来删除表中的所有行。TRUNCATE会快速地删除一组表中的所有行。 它与每个表上的未限定DELETE具有相同的效果,但由于它实际上没有扫描表,所以速度更快。此外,它立即回收磁盘空间,而不需要后续的VACUUM操作。这在大型表格上最有用。 http://www.postgresql.org/docs/9.1/static/sql-truncate.html

处理其他表引用的表:

当你有一个数据库包含多个表时,这些表可能存在关系。例如,有三个表:

create table customers (
customer_id int not null,
name varchar(20),
surname varchar(30),
constraint pk_customer primary key (customer_id)
);

create table orders (
order_id int not null,
number int not null,
customer_id int not null,
constraint pk_order primary key (order_id),
constraint fk_customer foreign key (customer_id) references customers(customer_id)
);

create table loyalty_cards (
card_id int not null,
card_number varchar(10) not null,
customer_id int not null,
constraint pk_card primary key (card_id),
constraint fk_customer foreign key (customer_id) references customers(customer_id)
);

以下是这些表的一些预先准备好的数据:

insert into customers values (1, 'John', 'Smith');

insert into orders values 
(10, 1000, 1),
(11, 1009, 1),
(12, 1010, 1);        

insert into loyalty_cards values (100, 'A123456789', 1);

表 orders 引用了表 customers,而表 loyalty_cards 也引用了表 customers。当你试图截断(TRUNCATE)/从被其它表所引用的表中删除数据时,你会遇到错误。如果你想要删除这三个表中的所有数据,你需要命名这些表(顺序不重要)。

TRUNCATE customers, loyalty_cards, orders;

或者只是使用CASCADE关键字引用的表(您可以引用多个表,而不仅仅是一个)

TRUNCATE customers CASCADE;

对于pgAdmin也是一样的。右键单击“customers”表,然后选择“级联截断”。


TRUNCATE 是 ANSI SQL 的一部分,并且在所有 DBMS 中都得到支持。我点击了链接,但是文档中并没有提到任何扩展。也许链接不正确或已过时? - Manngo
嗯,有趣。引用的文本仍然可以在此处找到:https://www.postgresql.org/docs/9.0/static/sql-delete.html 但是你是对的 - 它不在9.1的文档中。 - vitfo

64

对于表格,DELETE通常更快且需要更少的锁定(对于并发加载很重要):

DELETE FROM tbl;

没有WHERE条件。

对于中等或更大的表格,使用TRUNCATE,就像@Greg发布的那样:

TRUNCATE tbl;

很难确定“小型”和“大型”之间的界线,因为这取决于许多变量。您需要在您的安装中进行测试。


7
"small"、"medium"和"bigger"(根据您的估计)是什么? - Jackson
4
@Jackson:这很难准确界定,因为它取决于太多的变量。您可以运行一些测试来找到系统的最佳状态。 - Erwin Brandstetter

9

我发现了一种非常简单和快速的方法,适用于可能会使用像DBeaver这样的工具的所有人:

你只需要选择要截断的所有表格(SHIFT + 单击CTRL + 单击),然后右键单击

在这里输入图片描述

如果你有外键,还需在设置面板上选择CASCADE选项。点击开始,这就是全部所需了!


1
截断所有存在于PostgreSQL数据库中的表
SET session_replication_role = 'replica';


SELECT tablename FROM pg_tables WHERE schemaname = 'schemaname';

-- Generate and execute the truncate command for each table
DO $$ DECLARE
    table_name TEXT;
BEGIN
    FOR table_name IN (SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'schemaname') LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(table_name) || ' CASCADE;';
    END LOOP;
END $$;


SET session_replication_role = 'origin';


COMMIT;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接