PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL के लिए जेनरेट किए गए कॉलम का अवलोकन

PostgreSQL 12 एक बेहतरीन नई सुविधा, जेनरेटेड कॉलम के साथ आता है। कार्यक्षमता बिल्कुल नई नहीं है, लेकिन इस नए संस्करण में मानकीकरण, उपयोग में आसानी, पहुंच और प्रदर्शन में सुधार किया गया है।

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

PostgreSQL 12+ में जेनरेट किए गए कॉलम

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

  • डेटा उत्पन्न करने के लिए एप्लिकेशन कोड को अपडेट करने की आवश्यकता के बिना गणना किए गए डेटा वाली तालिका में एक कॉलम जोड़ने की क्षमता, फिर इसे INSERT और UPDATE संचालन में शामिल करें।
  • अत्यधिक बार-बार SELECT स्टेटमेंट पर प्रोसेसिंग समय कम करना जो डेटा को तुरंत प्रोसेस करेगा। चूंकि डेटा की प्रोसेसिंग INSERT या UPDATE के समय की जाती है, डेटा एक बार उत्पन्न होता है और SELECT स्टेटमेंट को केवल डेटा को पुनः प्राप्त करने की आवश्यकता होती है। भारी पठन वातावरण में, यह बेहतर हो सकता है, जब तक उपयोग किया गया अतिरिक्त डेटा संग्रहण स्वीकार्य है।
  • चूंकि जेनरेट किए गए कॉलम स्वचालित रूप से अपडेट हो जाते हैं जब स्रोत डेटा स्वयं अपडेट हो जाता है, जेनरेट किए गए कॉलम को जोड़ने से एक अनुमानित गारंटी मिल जाएगी कि जेनरेट किए गए कॉलम में डेटा हमेशा सही होता है।

PostgreSQL 12 में, केवल 'STORED' प्रकार का जनरेट किया गया कॉलम उपलब्ध है। अन्य डेटाबेस सिस्टम में, 'वर्चुअल' प्रकार के साथ एक जेनरेट किया गया कॉलम उपलब्ध है, जो एक ऐसे दृश्य की तरह कार्य करता है जहां डेटा पुनर्प्राप्त होने पर परिणाम की गणना फ्लाई पर की जाती है। चूंकि कार्यक्षमता विचारों के समान है, और केवल एक चयन कथन में ऑपरेशन लिखना, कार्यक्षमता यहां चर्चा की गई 'स्टोरेड' कार्यक्षमता के रूप में फायदेमंद नहीं है, लेकिन एक मौका है कि भविष्य के संस्करणों में सुविधा शामिल होगी।

एक जेनरेट किए गए कॉलम के साथ एक टेबल बनाना कॉलम को परिभाषित करते समय ही किया जाता है। इस उदाहरण में, उत्पन्न कॉलम 'लाभ' है, और बिक्री_प्राइस कॉलम से खरीद_प्राइस घटाकर स्वचालित रूप से उत्पन्न होता है, फिर मात्रा_सोल्ड कॉलम से गुणा किया जाता है।

CREATE TABLE public.transactions (

    transactions_sid serial primary key,

    transaction_date timestamp with time zone DEFAULT now() NOT NULL,

    product_name character varying NOT NULL,

    purchase_price double precision NOT NULL,

    sale_price double precision NOT NULL,

    quantity_sold integer NOT NULL,

    profit double precision NOT NULL GENERATED ALWAYS AS  ((sale_price - purchase_price) * quantity_sold) STORED

);

इस उदाहरण में, एक काल्पनिक कॉफी शॉप के कुछ बुनियादी लेनदेन और मुनाफे को ट्रैक करने के लिए एक 'लेन-देन' तालिका बनाई गई है। इस तालिका में डेटा डालने से कुछ तात्कालिक परिणाम दिखाई देंगे।

​severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('House Blend Coffee', 5, 11.99, 1);

severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('French Roast Coffee', 6, 12.99, 4);

severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('BULK: House Blend Coffee, 10LB', 40, 100, 6);



severalnines=# SELECT * FROM public.transactions;

 transactions_sid |       transaction_date |          product_name | purchase_price | sale_price | quantity_sold | profit

------------------+-------------------------------+--------------------------------+----------------+------------+---------------+--------

                1 | 2020-02-28 04:50:06.626371+00 | House Blend Coffee             | 5 | 11.99 | 1 | 6.99

                2 | 2020-02-28 04:50:53.313572+00 | French Roast Coffee            | 6 | 12.99 | 4 | 27.96

                3 | 2020-02-28 04:51:08.531875+00 | BULK: House Blend Coffee, 10LB |             40 | 100 | 6 | 360

पंक्ति को अपडेट करते समय, जनरेट किया गया कॉलम अपने आप अपडेट हो जाएगा:

​severalnines=# UPDATE public.transactions SET sale_price = 95 WHERE transactions_sid = 3;

UPDATE 1



severalnines=# SELECT * FROM public.transactions WHERE transactions_sid = 3;

 transactions_sid |       transaction_date |          product_name | purchase_price | sale_price | quantity_sold | profit

------------------+-------------------------------+--------------------------------+----------------+------------+---------------+--------

                3 | 2020-02-28 05:55:11.233077+00 | BULK: House Blend Coffee, 10LB |             40 | 95 | 6 | 330

यह सुनिश्चित करेगा कि जनरेट किया गया कॉलम हमेशा सही है, आवेदन पक्ष पर किसी अतिरिक्त तर्क की आवश्यकता नहीं है।

ध्यान दें:जेनरेट किए गए कॉलम को सीधे सम्मिलित या अद्यतन नहीं किया जा सकता है, और ऐसा करने का कोई भी प्रयास एक त्रुटि में वापस आ जाएगा:

severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold, profit) VALUES ('BULK: House Blend Coffee, 10LB', 40, 95, 1, 95);

ERROR:  cannot insert into column "profit"

DETAIL:  Column "profit" is a generated column.



severalnines=# UPDATE public.transactions SET profit = 330 WHERE transactions_sid = 3;

ERROR:  column "profit" can only be updated to DEFAULT

DETAIL:  Column "profit" is a generated column.

PostgreSQL 11 और उससे पहले के कॉलम जेनरेट किए गए हैं

भले ही बिल्ट-इन जेनरेट किए गए कॉलम PostgreSQL के संस्करण 12 में नए हैं, कार्यात्मक रूप से अभी भी पुराने संस्करणों में हासिल किया जा सकता है, इसे संग्रहीत प्रक्रियाओं और ट्रिगर्स के साथ बस थोड़ा और सेटअप की आवश्यकता है। हालांकि, पुराने संस्करणों पर इसे लागू करने की क्षमता के साथ, अतिरिक्त कार्यक्षमता के अलावा जो फायदेमंद हो सकती है, सख्त डेटा इनपुट अनुपालन प्राप्त करना कठिन है, और पीएल/पीजीएसक्यूएल सुविधाओं और प्रोग्रामिंग सरलता पर निर्भर करता है।

बोनस:नीचे दिया गया उदाहरण PostgreSQL 12+ पर भी काम करेगा, इसलिए यदि फ़ंक्शन / ट्रिगर कॉम्बो के साथ अतिरिक्त कार्यक्षमता की आवश्यकता है या नए संस्करणों में वांछित है, तो यह विकल्प एक वैध फ़ॉलबैक है और प्रतिबंधित नहीं है केवल 12 से पुराने संस्करण।

जबकि यह PostgreSQL के पिछले संस्करणों पर ऐसा करने का एक तरीका है, इस पद्धति के कुछ अतिरिक्त लाभ हैं: 

  • चूंकि जेनरेट किए गए कॉलम की नकल करने से फ़ंक्शन का उपयोग होता है, इसलिए अधिक जटिल गणनाओं का उपयोग किया जा सकता है। संस्करण 12 में जेनरेट किए गए कॉलम में अपरिवर्तनीय संचालन की आवश्यकता होती है, लेकिन एक ट्रिगर/फ़ंक्शन विकल्प अधिक संभावनाओं और संभावित रूप से कम प्रदर्शन के साथ एक स्थिर या अस्थिर प्रकार के फ़ंक्शन का उपयोग कर सकता है।
  • एक फ़ंक्शन का उपयोग करना जिसमें स्थिर या अस्थिर होने का विकल्प होता है, अतिरिक्त कॉलम अपडेट करने, अन्य तालिकाओं को अपडेट करने, या यहां तक ​​​​कि अन्य तालिकाओं में INSERTS के माध्यम से नया डेटा बनाने की संभावना को खोलता है। (हालांकि, जबकि ये ट्रिगर / फ़ंक्शन विकल्प अधिक लचीले होते हैं, इसका मतलब यह नहीं है कि वास्तविक "जेनरेटेड कॉलम" की कमी है, क्योंकि यह वही करता है जो अधिक प्रदर्शन और दक्षता के साथ विज्ञापित होता है।)

इस उदाहरण में, एक ट्रिगर / फ़ंक्शन को PostgreSQL 12+ जेनरेट किए गए कॉलम की कार्यक्षमता की नकल करने के लिए सेट किया गया है, साथ ही दो टुकड़े जो अपवाद उत्पन्न करते हैं यदि कोई INSERT या UPDATE जेनरेट किए गए कॉलम को बदलने का प्रयास करता है . इन्हें छोड़ा जा सकता है, लेकिन यदि इन्हें छोड़ दिया जाता है, तो अपवाद नहीं उठाए जाएंगे, और वास्तविक डेटा INSERTed या UPDATEd को चुपचाप त्याग दिया जाएगा, जिसकी आमतौर पर अनुशंसा नहीं की जाएगी।

ट्रिगर स्वयं पहले से चलने के लिए सेट है, जिसका अर्थ है कि वास्तविक इंसर्ट होने से पहले प्रसंस्करण होता है, और इसके लिए RETURN की आवश्यकता होती है, जो कि RECORD है जिसे नए जेनरेट किए गए कॉलम मान को शामिल करने के लिए संशोधित किया गया है। यह विशिष्ट उदाहरण PostgreSQL संस्करण 11 पर चलने के लिए लिखा गया था।

CREATE TABLE public.transactions (

    transactions_sid serial primary key,

    transaction_date timestamp with time zone DEFAULT now() NOT NULL,

    product_name character varying NOT NULL,

    purchase_price double precision NOT NULL,

    sale_price double precision NOT NULL,

    quantity_sold integer NOT NULL,

    profit double precision NOT NULL

);



CREATE OR REPLACE FUNCTION public.generated_column_function()

 RETURNS trigger

 LANGUAGE plpgsql

 IMMUTABLE

AS $function$

BEGIN



    -- This statement mimics the ERROR on built in generated columns to refuse INSERTS on the column and return an ERROR.

    IF (TG_OP = 'INSERT') THEN

        IF (NEW.profit IS NOT NULL) THEN

            RAISE EXCEPTION 'ERROR:  cannot insert into column "profit"' USING DETAIL = 'Column "profit" is a generated column.';

        END IF;

    END IF;



    -- This statement mimics the ERROR on built in generated columns to refuse UPDATES on the column and return an ERROR.

    IF (TG_OP = 'UPDATE') THEN

        -- Below, IS DISTINCT FROM is used because it treats nulls like an ordinary value. 

        IF (NEW.profit::VARCHAR IS DISTINCT FROM OLD.profit::VARCHAR) THEN

            RAISE EXCEPTION 'ERROR:  cannot update column "profit"' USING DETAIL = 'Column "profit" is a generated column.';

        END IF;

    END IF;



    NEW.profit := ((NEW.sale_price - NEW.purchase_price) * NEW.quantity_sold);

    RETURN NEW;



END;

$function$;




CREATE TRIGGER generated_column_trigger BEFORE INSERT OR UPDATE ON public.transactions FOR EACH ROW EXECUTE PROCEDURE public.generated_column_function();

ध्यान दें:सुनिश्चित करें कि फ़ंक्शन में वांछित एप्लिकेशन उपयोगकर्ता (उपयोगकर्ताओं) द्वारा निष्पादित करने के लिए सही अनुमति/स्वामित्व है।

जैसा कि पिछले उदाहरण में देखा गया है, फ़ंक्शन / ट्रिगर समाधान के साथ पिछले संस्करणों में परिणाम समान हैं:

​severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('House Blend Coffee', 5, 11.99, 1);

severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('French Roast Coffee', 6, 12.99, 4);

severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold) VALUES ('BULK: House Blend Coffee, 10LB', 40, 100, 6);



severalnines=# SELECT * FROM public.transactions;

 transactions_sid |       transaction_date |          product_name | purchase_price | sale_price | quantity_sold | profit

------------------+-------------------------------+--------------------------------+----------------+------------+---------------+--------

                1 | 2020-02-28 00:35:14.855511-07 | House Blend Coffee             | 5 | 11.99 | 1 | 6.99

                2 | 2020-02-28 00:35:21.764449-07 | French Roast Coffee            | 6 | 12.99 | 4 | 27.96

                3 | 2020-02-28 00:35:27.708761-07 | BULK: House Blend Coffee, 10LB |             40 | 100 | 6 | 360

डेटा अपडेट करना समान होगा।

​severalnines=# UPDATE public.transactions SET sale_price = 95 WHERE transactions_sid = 3;

UPDATE 1



severalnines=# SELECT * FROM public.transactions WHERE transactions_sid = 3;

 transactions_sid |       transaction_date |          product_name | purchase_price | sale_price | quantity_sold | profit

------------------+-------------------------------+--------------------------------+----------------+------------+---------------+--------

                3 | 2020-02-28 00:48:52.464344-07 | BULK: House Blend Coffee, 10LB |             40 | 95 | 6 | 330

अंत में, विशेष कॉलम में INSERT या UPDATE करने का प्रयास करने पर एक त्रुटि होगी:

​severalnines=# INSERT INTO public.transactions (product_name, purchase_price, sale_price, quantity_sold, profit) VALUES ('BULK: House Blend Coffee, 10LB', 40, 95, 1, 95);

ERROR:  ERROR: cannot insert into column "profit"

DETAIL:  Column "profit" is a generated column.

CONTEXT:  PL/pgSQL function generated_column_function() line 7 at RAISE



severalnines=# UPDATE public.transactions SET profit = 3030 WHERE transactions_sid = 3;

ERROR:  ERROR: cannot update column "profit"

DETAIL:  Column "profit" is a generated column.

CONTEXT:  PL/pgSQL function generated_column_function() line 15 at RAISE

इस उदाहरण में, यह पहले जेनरेट किए गए कॉलम सेटअप की तुलना में कुछ तरीकों से अलग तरह से कार्य करता है जिन पर ध्यान दिया जाना चाहिए:

  • यदि 'जनरेटेड कॉलम' को अपडेट करने का प्रयास किया जाता है, लेकिन कोई पंक्ति अपडेट नहीं पाई जाती है, तो यह "UPDATE 0" परिणाम के साथ सफलता लौटाएगा, जबकि संस्करण 12 में एक वास्तविक जेनरेटेड कॉलम अभी भी होगा एक त्रुटि लौटाएं, भले ही अद्यतन करने के लिए कोई पंक्ति न मिले।
  • लाभ कॉलम को अपडेट करने का प्रयास करते समय, जिसे 'हमेशा' एक त्रुटि लौटानी चाहिए, यदि निर्दिष्ट मान सही 'जेनरेट' मान के समान है, तो यह सफल होगा। अंततः डेटा सही है, हालांकि, यदि कॉलम निर्दिष्ट होने पर एक त्रुटि वापस करने की इच्छा है।

दस्तावेज़ीकरण और PostgreSQL समुदाय

पोस्टग्रेएसक्यूएल जेनरेटेड कॉलम के लिए आधिकारिक दस्तावेज आधिकारिक पोस्टग्रेएसक्यूएल वेबसाइट पर स्थित है। जब पोस्टग्रेएसक्यूएल के नए प्रमुख संस्करण दिखाई देते हैं तो नई सुविधाओं की खोज करने के लिए वापस जांचें।

जबकि PostgreSQL 12 में जेनरेट किए गए कॉलम काफी सीधे हैं, पिछले संस्करणों में समान कार्यक्षमता को लागू करने से और अधिक जटिल होने की संभावना है। PostgreSQL समुदाय एक बहुत ही सक्रिय, विशाल, विश्वव्यापी और बहुभाषी समुदाय है जो PostgreSQL के किसी भी स्तर के लोगों की समस्याओं को हल करने और इस तरह के नए समाधान बनाने में मदद करने के लिए समर्पित है।

  • आईआरसी :फ़्रीनोड का एक बहुत ही सक्रिय चैनल है जिसे #postgres कहा जाता है, जहां उपयोगकर्ता अवधारणाओं को समझने, त्रुटियों को ठीक करने, या अन्य संसाधन खोजने में एक-दूसरे की मदद करते हैं। सभी चीज़ों के लिए उपलब्ध फ़्रीनोड चैनलों की पूरी सूची PostgreSQL को PostgreSQL.org वेबसाइट पर पाया जा सकता है।
  • मेलिंग सूचियां :PostgreSQL में मुट्ठी भर मेलिंग सूचियाँ हैं जिन्हें जोड़ा जा सकता है। लंबे फॉर्म वाले प्रश्न/मुद्दे यहां भेजे जा सकते हैं, और किसी भी समय आईआरसी की तुलना में कई अधिक लोगों तक पहुंच सकते हैं। सूचियाँ PostgreSQL वेबसाइट पर पाई जा सकती हैं, और सूचियाँ pgsql-General या pgsql-admin अच्छे संसाधन हैं।
  • सुस्त :PostgreSQL समुदाय भी स्लैक पर फल-फूल रहा है, और इसे postgresteam.slack.com पर शामिल किया जा सकता है। आईआरसी की तरह, एक सक्रिय समुदाय सवालों के जवाब देने और पोस्टग्रेएसक्यूएल की सभी चीजों में संलग्न होने के लिए उपलब्ध है।

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL की छिपी विशेषताएं

  2. कैसे pg_sleep () PostgreSQL में काम करता है

  3. किसी अन्य तालिका के लिए विदेशी कुंजी के रूप में उपयोग की जाने वाली स्वत:जेनरेट की गई प्राथमिक कुंजी का निर्धारण कैसे करें

  4. PostgreSQL में पाठ संपीड़न

  5. PostgreSQL में मॉड () कैसे काम करता है