पोस्टग्रेज में एक टेबल (इंडेक्स सहित) कॉपी करें


85

मेरे पास पोस्टग्रेज टेबल है। मुझे इससे कुछ डेटा हटाने की आवश्यकता है। मैं एक अस्थायी तालिका बनाने जा रहा था, डेटा को कॉपी करूं, अनुक्रमित और फिर से आवश्यक पंक्तियों को हटा दूं। मैं मूल तालिका से डेटा हटा नहीं सकता, क्योंकि यह मूल तालिका डेटा का स्रोत है। एक मामले में मुझे कुछ परिणाम प्राप्त करने की आवश्यकता है जो एक्स को हटाने पर निर्भर करता है, दूसरे मामले में, मुझे वाई को हटाने की आवश्यकता होगी। इसलिए मुझे हमेशा और आसपास उपलब्ध होने के लिए सभी मूल डेटा की आवश्यकता होती है।

हालांकि यह तालिका को फिर से बनाने और इसे फिर से कॉपी करने और अनुक्रमित को फिर से बनाने के लिए थोड़ा मूर्खतापूर्ण लगता है। वैसे भी यह बताने के लिए पोस्टग्रेज में है "मुझे इस तालिका की पूरी अलग कॉपी चाहिए, जिसमें संरचना, डेटा और इंडेक्स शामिल हैं"?

दुर्भाग्य से PostgreSQL के पास "सृजन तालिका" नहीं है। LIKE X INCLUDING INDEXES '

जवाबों:


108

नया पोस्टग्रैसक्यूएल (डॉक्स के अनुसार 8.3 के बाद से) "INCLUDING INDEXES" का उपयोग कर सकता है:

# 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)

यदि आप PostgreSQL प्री-8.3 का उपयोग कर रहे हैं, तो आप बस 1 टेबल निर्दिष्ट करने, डंप में टेबल का नाम बदलने और इसे फिर से लोड करने के लिए "-t" विकल्प के साथ pg_dump का उपयोग कर सकते हैं:

=> 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)

14
इस तरह प्राथमिक कुंजी अनुक्रम (X1_id_seq) दो तालिकाओं के बीच साझा किया जाएगा!
Jauzsika

2
ऑप्स, pg9.X के साथ, "INCLUDING CONSTRAINTS" ("INCLUING INDEXES" नहीं) का उपयोग करते समय प्राथमिक कुंजी अनुक्रम साझा किया जाएगा।
पीटर क्रस

44
[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 का पैच आउट होता है


पोस्टग्रे में कोई "INCLUDING INDEXES" नहीं है।
रोरी

2
आप किस संस्करण का उपयोग कर रहे हैं? नवीनतम डॉक पढ़ें, यह वहां है
वोल्फमैनड्रागन

6
pg9.X के साथ, जब "INCLUDING CONSTRAINTS" ("INCLUING INDEXES" नहीं) का उपयोग करते हुए प्राथमिक कुंजी क्रम को दो तालिकाओं (!) के बीच साझा किया जाएगा।
पीटर क्रूस

ऐसा लगता है कि काम करने के लिए CREATE TABLE my_table (LIKE...)इसके बजाय होना चाहिए CREATE TABLE my_table LIKE...। संपादित उत्तर।
जेसन स्वेट

@PeterKrauss क्या आपने साझा प्राथमिक कुंजी अनुक्रम चीज़ का पता लगाया है? मैं एक नई तालिका में डेटा का एक गुच्छा कॉपी करने की कोशिश कर रहा हूं। मैं पुरानी तालिका को नहीं छोड़ सकता और नए का नाम बदल सकता हूं क्योंकि पुराने पर नए अंक से पीके।
yellottyellott

4

मेरे पास पोस्टग्रेज टेबल है। मुझे इससे कुछ डेटा हटाने की आवश्यकता है।

मुझे लगता है कि ...

delete from yourtable
where <condition(s)>

... किसी कारण से काम नहीं करेगा। (ध्यान उस कारण को साझा करने के लिए?)

मैं एक अस्थायी तालिका बनाने जा रहा था, डेटा को कॉपी करूं, अनुक्रमित और फिर से आवश्यक पंक्तियों को हटा दूं।

Pg_dump और pg_restore में देखें। कुछ चालाक विकल्पों के साथ pg_dump का उपयोग करना और शायद pg_restoring से पहले आउटपुट को संपादित करना चाल हो सकता है।


चूँकि आप डेटा पर "क्या होगा अगर" का विश्लेषण कर रहे हैं, मुझे आश्चर्य है कि क्या आप विचारों का उपयोग करने से बेहतर हो सकते हैं।

आप उस प्रत्येक परिदृश्य के लिए एक दृश्य निर्धारित कर सकते हैं जिसे आप बाहर करना चाहते हैं की उपेक्षा के आधार पर परीक्षण करना चाहते हैं। यानी, जो आप INclude करना चाहते हैं, उसके आधार पर एक दृश्य परिभाषित करें। उदाहरण के लिए, यदि आप उस डेटा पर "विंडो" चाहते हैं, जहाँ आपने पंक्तियों को "जहाँ" हटा दिया है जहाँ X = Y है, तो आप पंक्तियों के रूप में एक दृश्य बनाएंगे जहाँ (X! = Y)।

दृश्य डेटाबेस में (सिस्टम कैटलॉग में) उनके परिभाषित क्वेरी के रूप में संग्रहीत किए जाते हैं। हर बार जब आप दृश्य को देखते हैं तो डेटाबेस सर्वर अंतर्निहित क्वेरी को देखता है जो इसे परिभाषित करता है और निष्पादित करता है (आपके द्वारा उपयोग की गई किसी भी अन्य शर्तों के साथ anded)। इस दृष्टिकोण के कई लाभ हैं:

  1. आप कभी भी अपने डेटा के किसी भी हिस्से की नकल नहीं करते हैं।
  2. जब आप प्रत्येक दृश्य / परिदृश्य को क्वेरी करते हैं तो बेस टेबल (आपके मूल, "वास्तविक" टेबल) के लिए पहले से उपयोग किए जाने वाले इंडेक्स का उपयोग किया जाएगा (जैसा कि क्वेरी ऑप्टिमाइज़र द्वारा देखा गया है)। उन्हें फिर से परिभाषित या कॉपी करने की कोई आवश्यकता नहीं है।
  3. चूंकि आधार तालिका में "वास्तविक" डेटा पर एक दृश्य "विंडो" (शाॅपशॉट नहीं है) है, आप अपने बेस टेबल पर जोड़ / अपडेट / हटा सकते हैं और बस कुछ भी दोबारा बनाने की आवश्यकता नहीं के साथ दृश्य परिदृश्यों को फिर से क्वेरी कर सकते हैं। डेटा समय के साथ बदलता है।

एक व्यापार बंद है, ज़ाहिर है। चूंकि एक दृश्य एक आभासी तालिका है और "वास्तविक" (आधार) तालिका नहीं है, आप वास्तव में इसे एक्सेस करने पर हर बार एक (शायद जटिल) क्वेरी निष्पादित कर रहे हैं। इससे चीजें थोड़ी धीमी हो सकती हैं। लेकिन ऐसा नहीं हो सकता। यह कई मुद्दों (डेटा की आकार और प्रकृति, सिस्टम कैटलॉग में आंकड़ों की गुणवत्ता, हार्डवेयर की गति, उपयोग लोड और बहुत कुछ) पर निर्भर करता है। जब तक आप कोशिश नहीं करेंगे, आपको पता नहीं चलेगा। यदि (और केवल अगर) आप वास्तव में पाते हैं कि प्रदर्शन अस्वीकार्य रूप से धीमा है, तो आप अन्य विकल्पों को देख सकते हैं। (भौतिक विचार, तालिकाओं की प्रतियां, ... कुछ भी जो समय के लिए स्थान का व्यापार करता है।)


मैंने यह बताने के लिए प्रश्न को अपडेट किया है कि मैं मूल तालिका से क्यों नहीं हटा सकता
रोरी

4

वेब पर कई उत्तर हैं, उनमें से एक यहां पाया जा सकता है

मैंने कुछ इस तरह से काम किया:

create table NEW ( like ORIGINAL including all);
insert into NEW select * from ORIGINAL

यह स्कीमा और डेटा को अनुक्रमित सहित कॉपी करेगा, लेकिन ट्रिगर्स और बाधाओं को शामिल नहीं करेगा। ध्यान दें कि अनुक्रमणिका को मूल तालिका के साथ साझा किया जाता है, इसलिए जब तालिका में नई पंक्ति जोड़ते हैं तो काउंटर बढ़ जाएगा।


1

अपने इच्छित डेटा को हथियाने के लिए एक चयन करके एक नई तालिका बनाएं। फिर नए के साथ पुरानी तालिका को स्वैप करें।

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

0

एक सरल तरीका सभी में शामिल है:

CREATE TABLE new_table (LIKE original_table INCLUDING ALL);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.