O novo PostgreSQL (desde 8.3 de acordo com os documentos) pode usar "INCLUINDO ÍNDICE":
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)
Como você pode ver, estou testando no 8.3.
Agora, vamos criar a tabela:
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
E veja como fica:
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)
Agora podemos copiar a estrutura:
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
E verifique a estrutura:
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)
Se você estiver usando PostgreSQL pré-8.3, você pode simplesmente usar pg_dump com a opção "-t" para especificar 1 tabela, alterar o nome da tabela no dump e carregá-la novamente:
=> 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
E agora a mesa é:
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]
Aqui está um exemplo
CREATE TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01';
A outra maneira de criar uma nova tabela a partir da primeira é usar
CREATE TABLE films_recent (LIKE films INCLUDING INDEXES); INSERT INTO films_recent SELECT * FROM books WHERE date_prod >= '2002-01-01';
Observe que o Postgresql tem um patch para corrigir problemas de espaço de tabela se o segundo método for usado
fonte
CREATE TABLE my_table (LIKE...)
vez deCREATE TABLE my_table LIKE...
para funcionar. Resposta editada.Existem muitas respostas na web, uma delas pode ser encontrada aqui .
Acabei fazendo algo assim:
create table NEW ( like ORIGINAL including all); insert into NEW select * from ORIGINAL
Isso copiará o esquema e os dados, incluindo índices, mas não incluindo gatilhos e restrições. Observe que os índices são compartilhados com a tabela original, portanto, ao adicionar uma nova linha a qualquer uma das tabelas, o contador aumentará.
fonte
Eu presumo que ...
delete from yourtable where <condition(s)>
... não funcionará por algum motivo. (Importa-se de compartilhar esse motivo?)
Procure em pg_dump e pg_restore. Usar o pg_dump com algumas opções inteligentes e talvez editar a saída antes do pg_restoring pode resolver o problema.
Já que você está fazendo uma análise do tipo "e se" nos dados, eu me pergunto se seria melhor usar visualizações.
Você pode definir uma visão para cada cenário que deseja testar com base na negação do que deseja excluir. Ou seja, defina uma visualização com base no que você deseja incluir. Por exemplo, se você quiser uma "janela" nos dados onde você "excluiu" as linhas onde X = Y, então você criaria uma visualização como linhas onde (X! = Y).
As visualizações são armazenadas no banco de dados (no Catálogo do Sistema) como sua consulta de definição. Cada vez que você consulta a visualização, o servidor de banco de dados procura a consulta subjacente que a define e a executa (com AND com quaisquer outras condições que você usou). Existem vários benefícios para esta abordagem:
Há uma compensação, é claro. Como uma visão é uma tabela virtual e não uma tabela "real" (base), você está na verdade executando uma consulta (talvez complexa) toda vez que a acessa. Isso pode desacelerar um pouco as coisas. Mas pode não ser. Depende de muitos problemas (tamanho e natureza dos dados, qualidade das estatísticas no Catálogo do Sistema, velocidade do hardware, carga de uso e muito mais). Você não saberá até tentar. Se (e somente se) você realmente achar que o desempenho está inaceitavelmente lento, você pode procurar outras opções. (Visualizações materializadas, cópias de tabelas, ... qualquer coisa que troque espaço por tempo.)
fonte
Crie uma nova tabela usando um select para obter os dados desejados. Em seguida, troque a mesa antiga pela nova.
create table mynewone as select * from myoldone where ... mess (re-create) with indexes after the table swap.
fonte
Uma maneira simples é incluir tudo:
CREATE TABLE new_table (LIKE original_table INCLUDING ALL);
fonte