我有一张postgres表.我需要从中删除一些数据.我打算创建一个临时表,复制数据,重新创建索引并删除我需要的行.我无法从原始表中删除数据,因为此原始表是数据源.在一种情况下,我需要得到一些取决于删除X的结果,在另一种情况下,我需要删除Y.所以我需要所有的原始数据始终存在并可用.
然而,重新创建表并再次复制并重新创建索引似乎有点愚蠢.无论如何在postgres中告诉它"我想要一个完整的表格副本,包括结构,数据和索引"?
不幸的是,PostgreSQL没有"创建表......像X包含指数"
新的PostgreSQL(根据文档自8.3起)可以使用"包含索引":
# select version(); version ------------------------------------------------------------------------------------------------- PostgreSQL 8.3.7 on x86_64-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3) (1 row)
如你所见,我正在测试8.3.
现在,让我们创建表:
# create table x1 (id serial primary key, x text unique); NOTICE: CREATE TABLE will create implicit sequence "x1_id_seq" for serial column "x1.id" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "x1_pkey" for table "x1" NOTICE: CREATE TABLE / UNIQUE will create implicit index "x1_x_key" for table "x1" CREATE TABLE
看看它的样子:
# \d x1 Table "public.x1" Column | Type | Modifiers --------+---------+------------------------------------------------- id | integer | not null default nextval('x1_id_seq'::regclass) x | text | Indexes: "x1_pkey" PRIMARY KEY, btree (id) "x1_x_key" UNIQUE, btree (x)
现在我们可以复制结构:
# create table x2 ( like x1 INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES ); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "x2_pkey" for table "x2" NOTICE: CREATE TABLE / UNIQUE will create implicit index "x2_x_key" for table "x2" CREATE TABLE
并检查结构:
# \d x2 Table "public.x2" Column | Type | Modifiers --------+---------+------------------------------------------------- id | integer | not null default nextval('x1_id_seq'::regclass) x | text | Indexes: "x2_pkey" PRIMARY KEY, btree (id) "x2_x_key" UNIQUE, btree (x)
如果您使用的是pregreSQL 8.3之前的版本,则只需使用带选项"-t"的pg_dump指定1个表,在转储中更改表名,然后再次加载:
=> pg_dump -t x2 | sed 's/x2/x3/g' | psql SET SET SET SET SET SET SET SET CREATE TABLE ALTER TABLE ALTER TABLE ALTER TABLE
现在表是:
# \d x3 Table "public.x3" Column | Type | Modifiers --------+---------+------------------------------------------------- id | integer | not null default nextval('x1_id_seq'::regclass) x | text | Indexes: "x3_pkey" PRIMARY KEY, btree (id) "x3_x_key" UNIQUE, btree (x)
[CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name [ (column_name [, ...] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace ] AS query][1]
这是一个例子
CREATE TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01';
从第一个创建新表的另一种方法是使用
CREATE TABLE films_recent (LIKE films INCLUDING INDEXES); INSERT INTO films_recent SELECT * FROM books WHERE date_prod >= '2002-01-01';
请注意,如果使用第二种方法,Postgresql有一个补丁来修复表空间问题