复制postgres中的表(包括索引)

Ror*_*ory 82 sql postgresql indexing

我有一张postgres表.我需要从中删除一些数据.我打算创建一个临时表,复制数据,重新创建索引并删除我需要的行.我无法从原始表中删除数据,因为此原始表是数据源.在一种情况下,我需要得到一些取决于删除X的结果,在另一种情况下,我需要删除Y.所以我需要所有的原始数据始终存在并可用.

然而,重新创建表并再次复制并重新创建索引似乎有点愚蠢.无论如何在postgres中告诉它"我想要一个完整的表格副本,包括结构,数据和索引"?

不幸的是,PostgreSQL没有"创建表......像X包含指数"

小智 104

新的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)
Run Code Online (Sandbox Code Playgroud)

如你所见,我正在测试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
Run Code Online (Sandbox Code Playgroud)

看看它的样子:

# \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)
Run Code Online (Sandbox Code Playgroud)

现在我们可以复制结构:

# 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
Run Code Online (Sandbox Code Playgroud)

并检查结构:

# \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)
Run Code Online (Sandbox Code Playgroud)

如果您使用的是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
Run Code Online (Sandbox Code Playgroud)

现在表是:

# \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)
Run Code Online (Sandbox Code Playgroud)

  • 这样主键序列(x1_id_seq)将在两个表之间共享! (14认同)
  • Ops,使用pg9.X时,主键序列将在使用"INCLUDING CONSTRAINTS"(不包括"INCEXUING INDEXES")时共享. (2认同)

Wol*_*gon 43

[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]  
Run Code Online (Sandbox Code Playgroud)

这是一个例子

CREATE TABLE films_recent AS
  SELECT * FROM films WHERE date_prod >= '2002-01-01';
Run Code Online (Sandbox Code Playgroud)

从第一个创建新表的另一种方法是使用

    CREATE TABLE films_recent (LIKE films INCLUDING INDEXES);  

    INSERT INTO films_recent
         SELECT *
           FROM books
          WHERE date_prod >= '2002-01-01';  
Run Code Online (Sandbox Code Playgroud)

请注意,如果使用第二种方法,Postgresql有一个补丁来修复表空间问题

  • 使用pg9.X,当使用"INCLUDING CONSTRAINTS"(不是"INCLUING INDEXES")时,主键序列将在两个表(!)之间共享. (6认同)
  • 你用的是哪个版本?阅读最新的文档,就在那里 (2认同)

osh*_*hai 11

网上有很多答案,其中之一可以在这里找到。

我最终做了这样的事情:

create table NEW ( like ORIGINAL including all);
insert into NEW select * from ORIGINAL
Run Code Online (Sandbox Code Playgroud)

这将复制架构和数据,包括索引,但不包括触发器和约束。请注意,索引与原始表共享,因此当向任一表添加新行时,计数器将增加。

  • 根据 https://www.postgresql.org/docs/current/sql-createtable.html,“请注意,索引与原始表共享,因此当向任一表添加新行时,计数器将增加。” 会错吗? (2认同)

小智 1

使用选择创建一个新表以获取所需的数据。然后将旧表与新表交换。

create table mynewone as select * from myoldone where ...
mess (re-create) with indexes after the table swap.
Run Code Online (Sandbox Code Playgroud)