Nowy PostgreSQL (od 8.3 według dokumentacji) może używać "INCLUDING INDEXES":
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)
Jak widać, testuję na 8.3.
Teraz stwórzmy tabelę:
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
I zobacz, jak to wygląda:
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)
Teraz możemy skopiować strukturę:
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
I sprawdź strukturę:
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)
Jeśli używasz PostgreSQL w wersji starszej niż 8.3, możesz po prostu użyć pg_dump z opcją "-t", aby określić 1 tabelę, zmienić nazwę tabeli w zrzucie i załadować ją ponownie:
=> 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
A teraz tabela jest:
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]
Oto przykład
CREATE TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01';
Innym sposobem na utworzenie nowej tabeli z pierwszej jest użycie
CREATE TABLE films_recent (LIKE films INCLUDING INDEXES); INSERT INTO films_recent SELECT * FROM books WHERE date_prod >= '2002-01-01';
Zauważ, że Postgresql ma łatkę , która rozwiązuje problemy z obszarami tabel, jeśli używana jest druga metoda
źródło
CREATE TABLE my_table (LIKE...)
zamiastCREATE TABLE my_table LIKE...
, aby działał. Edytowana odpowiedź.Zakładam, że ...
delete from yourtable where <condition(s)>
... nie zadziała z jakiegoś powodu. (Chcesz podzielić się tym powodem?)
Zajrzyj do pg_dump i pg_restore. Używanie pg_dump z kilkoma sprytnymi opcjami i być może edycja wyniku przed pg_restoring może załatwić sprawę.
Ponieważ wykonujesz analizę danych typu „a co, jeśli”, zastanawiam się, czy nie byłoby lepiej, gdybyś korzystał z widoków.
Możesz zdefiniować widok dla każdego scenariusza, który chcesz przetestować, na podstawie negacji tego, co chcesz wykluczyć. To znaczy zdefiniuj widok na podstawie tego, co chcesz uwzględnić. Na przykład, jeśli chcesz mieć „okno” na danych, w którym „usunąłeś” wiersze, w których X = Y, to utworzyłbyś widok jako wiersze, w których (X! = Y).
Widoki są przechowywane w bazie danych (w katalogu systemowym) jako ich definiujące zapytanie. Za każdym razem, gdy wysyłasz zapytanie do widoku, serwer bazy danych wyszukuje podstawowe zapytanie, które go definiuje i wykonuje to (połączone operatorem AND z innymi użytymi warunkami). Takie podejście ma kilka zalet:
Oczywiście istnieje kompromis. Ponieważ widok jest tabelą wirtualną, a nie „prawdziwą” (podstawową) tabelą, w rzeczywistości wykonujesz (być może złożone) zapytanie za każdym razem, gdy uzyskujesz do niego dostęp. Może to trochę spowolnić. Ale może nie. Zależy to od wielu kwestii (rozmiar i charakter danych, jakość statystyk w katalogu systemowym, szybkość sprzętu, obciążenie użytkowe i wiele innych). Nie dowiesz się, dopóki tego nie spróbujesz. Jeśli (i tylko jeśli) rzeczywiście okaże się, że wydajność jest niedopuszczalnie wolna, możesz rozważyć inne opcje. (Zmaterializowane widoki, kopie tabel, ... wszystko, co zamienia przestrzeń na czas.)
źródło
W sieci jest wiele odpowiedzi, jedną z nich można znaleźć tutaj .
W końcu zrobiłem coś takiego:
create table NEW ( like ORIGINAL including all); insert into NEW select * from ORIGINAL
Spowoduje to skopiowanie schematu i danych, w tym indeksów, ale bez wyzwalaczy i ograniczeń. Zauważ, że indeksy są współdzielone z oryginalną tabelą, więc podczas dodawania nowego wiersza do którejkolwiek z tabel licznik będzie się zwiększał.
źródło
Utwórz nową tabelę, używając funkcji wyboru, aby pobrać żądane dane. Następnie zamień stary stół na nowy.
create table mynewone as select * from myoldone where ... mess (re-create) with indexes after the table swap.
źródło
Prostym sposobem jest uwzględnienie wszystkich:
CREATE TABLE new_table (LIKE original_table INCLUDING ALL);
źródło