PostgreSQL में गणना / गणना / आभासी / व्युत्पन्न कॉलम


113

क्या PostgreSQL MS SQL सर्वर की तरह गणना / परिकलित कॉलम का समर्थन करता है? मुझे डॉक्स में कुछ भी नहीं मिल रहा है, लेकिन जैसा कि यह सुविधा कई अन्य डीबीएमएस में शामिल है, मुझे लगा कि मुझे कुछ याद आ रहा है।

जैसे: http://msdn.microsoft.com/en-us/library/ms191250.aspx


पार्श्व सबक्वेरी एक्सप्रेशन (पोस्टग्रेज फीचर) का उपयोग करके आप आसानी से प्रत्येक पंक्ति में अधिक कॉलम जोड़ सकते हैं।
विक्टर

जवाबों:


139

पोस्टग्रैज तक 11 उत्पन्न कॉलम समर्थित नहीं हैं - जैसा कि SQL मानक में परिभाषित किया गया है और DB2, MySQL और Oracle सहित कुछ RDBMS द्वारा कार्यान्वित किया गया है। और न ही SQL सर्वर के समान "कंप्यूटेड कॉलम"

STOREDपोस्ट किए गए 12 के साथ उत्पन्न कॉलम पेश किए जाते हैं । तुच्छ उदाहरण:

CREATE TABLE tbl (
  int1    int
, int2    int
, product bigint GENERATED ALWAYS AS (int1 * int2) STORED
);

db <> फिडल यहां

VIRTUALउत्पन्न कॉलम अगले पुनरावृत्तियों में से एक के साथ आ सकते हैं। (पोस्टग्रेस 13 में नहीं, फिर भी)।

सम्बंधित:


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

अभिव्यक्ति (एक स्तंभ की तरह दिखना) को SELECT * FROM tblहालांकि, में शामिल नहीं किया गया है । आपको हमेशा इसे स्पष्ट रूप से सूचीबद्ध करना होगा।

एक मिलान अभिव्यक्ति सूचकांक के साथ भी समर्थन किया जा सकता है - बशर्ते फ़ंक्शन है IMMUTABLE। पसंद:

CREATE FUNCTION col(tbl) ... AS ...  -- your computed expression here
CREATE INDEX ON tbl(col(tbl));

वैकल्पिक

वैकल्पिक रूप से, आप ए के साथ समान कार्यक्षमता लागू कर सकते हैं VIEW, वैकल्पिक रूप से अभिव्यक्ति सूचकांक के साथ मिलकर। फिरSELECT * उत्पन्न कॉलम को शामिल कर सकते हैं।

"Persistent" ( STORED) गणना किए गए कॉलम को कार्यात्मक रूप से समान तरीके से ट्रिगर के साथ लागू किया जा सकता है ।

भौतिकवादी विचार एक निकट से संबंधित अवधारणा है, जिसे पोस्टग्रेज 9.3 से लागू किया गया है
पहले के संस्करणों में कोई भी मैन्युअल रूप से MVs प्रबंधित कर सकता है।


एक बार में आप कितना डेटा लोड कर रहे हैं इसके आधार पर .. ट्रिगर चीजों को काफी धीमा कर सकता है। इसके बजाय अपडेट पर विचार करना चाहते हैं।
सम य

1
ये समाधान बहुत बेकार हैं (बिना किसी परीक्षण के मामलों के साथ एक कोडबेस के लिए बड़े कोड में बदलाव के बिना) जब संधि से पोस्टग्रेज में पलायन होता है। क्या प्रवास के दृष्टिकोण से कोई समाधान है?
खुशबुधा

@happybuddha: कृपया अपना प्रश्न प्रश्न के रूप में पूछें। टिप्पणियाँ जगह नहीं हैं। आप हमेशा इस प्रश्न को संदर्भ के लिए लिंक कर सकते हैं (और मेरा ध्यान और संबंधित प्रश्न से लिंक करने के लिए यहां एक टिप्पणी जोड़ें)।
इरविन ब्रान्डसेट्टर

4
कार्यक्षमता अभी विकास में है: कमिटमेंट। postgresql.org/16/1443
r90t

1
@ क्रैनभू: आपके सेटअप और आवश्यकताओं के विवरण पर निर्भर करता है। आप आवश्यक जानकारी के साथ एक नया प्रश्न पूछ सकते हैं।
एरविन ब्रान्डस्टैटर

32

हाँ तुम कर सकते हो!! समाधान आसान, सुरक्षित और प्रदर्शनकारी होना चाहिए ...

मैं postgresql के लिए नया हूं, लेकिन ऐसा लगता है कि आप एक का उपयोग करके गणना किए गए कॉलम बना सकते हैं अभिव्यक्ति सूचकांक , एक दृश्य के साथ युग्मित (दृश्य वैकल्पिक है, लेकिन इससे जीवन थोड़ा आसान हो जाता है)।

मान लीजिए मेरी गणना है md5(some_string_field) , तो मैं सूचकांक बनाता हूं:

CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field));

अब, कोई भी प्रश्न जो कार्य करता है MD5(some_string_field) करती है, वह स्क्रैच से गणना करने के बजाय सूचकांक का उपयोग करेगी। उदाहरण के लिए:

SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field);

आप इससे जांच कर सकते हैं व्याख्या

हालाँकि इस बिंदु पर आप तालिका के उपयोगकर्ताओं पर भरोसा कर रहे हैं कि कॉलम का निर्माण कैसे किया जाता है। जीवन को आसान बनाने के लिए, आप एक बना सकते हैंVIEW मूल तालिका के संवर्धित संस्करण पर एक नया कॉलम के रूप में गणना किए गए मूल्य को जोड़ सकते हैं:

CREATE VIEW some_table_augmented AS 
   SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table;

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

संपादित करें: ऐसा लगता है कि यदि क्वेरी में प्रतिस्पर्धी सूचकांक शामिल हैं, तो योजनाकार इंजन कभी-कभी अभिव्यक्ति-सूचकांक का उपयोग नहीं कर सकता है। चुनाव डेटा पर निर्भर लगता है।


1
क्या आप इसका उदाहरण या व्याख्या कर सकते हैं if the query involves competing indices?
dvtan

17

ऐसा करने का एक तरीका ट्रिगर के साथ है!

CREATE TABLE computed(
    one SERIAL,
    two INT NOT NULL
);

CREATE OR REPLACE FUNCTION computed_two_trg()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
    NEW.two = NEW.one * 2;

    RETURN NEW;
END
$BODY$;

CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATE
ON computed
FOR EACH ROW
EXECUTE PROCEDURE computed_two_trg();

ट्रिगर को अपडेट या डालने से पहले ट्रिगर निकाल दिया जाता है। यह उस क्षेत्र को बदल देता है जिसे हम NEWरिकॉर्ड की गणना करना चाहते हैं और फिर यह उस रिकॉर्ड को वापस कर देता है।


ट्रिगर अक्यूटली फायर कब करता है? मैं ऊपर भागा insert into computed values(1, 2); insert into computed values(4, 8); commit; select * from computed;और यह किया और यह अभी लौटा: 1 2 और 4 8
खुशबुधा

2
प्रयास insert into computed(one) values(1); insert into computed(one) values(4); commit; select * from computed;करें कि twoस्तंभ का मान स्वचालित रूप से परिकलित किया जाएगा!
एल्मर

8

PostgreSQL 12 उत्पन्न कॉलम का समर्थन करता है:

PostgreSQL 12 बीटा 1 का विमोचन!

कॉलम बनाए गए

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


कॉलम बनाए गए

एक उत्पन्न स्तंभ एक विशेष स्तंभ है जो हमेशा अन्य स्तंभों से गणना की जाती है। इस प्रकार, यह उन स्तंभों के लिए है जो तालिकाओं के लिए एक दृश्य है।

CREATE TABLE people (
    ...,
    height_cm numeric,
    height_in numeric GENERATED ALWAYS AS (height_cm * 2.54) STORED
);

db <> फिडेल डेमो



1

ठीक है, यह सुनिश्चित नहीं है कि यह वही है जो आप का मतलब है, लेकिन आमतौर पर पॉज़्रेग "डमी" ईटीएल सिंटैक्स का समर्थन करते हैं। मैंने तालिका में एक खाली कॉलम बनाया और फिर उसे पंक्ति में मानों के आधार पर गणना किए गए रिकॉर्डों को भरने की आवश्यकता थी।

UPDATE table01
SET column03 = column01*column02; /*e.g. for multiplication of 2 values*/
  1. यह इतना डमी है मुझे संदेह है कि यह वह नहीं है जो आप ढूंढ रहे हैं।
  2. जाहिर है कि यह गतिशील नहीं है, आप इसे एक बार चलाते हैं। लेकिन इसे ट्रिगर में लाने के लिए कोई बाधा नहीं है।

0

मेरे पास एक कोड है जो गणना किए गए शब्द का उपयोग करता है और उपयोग करता है, मैं पोस्टग्रैसक्यूएल शुद्ध थियो पर नहीं हूं जो हम पीएडीबी पर चलाते हैं

यहाँ इसका उपयोग कैसे किया जाता है

create table some_table as
    select  category, 
            txn_type,
            indiv_id, 
            accum_trip_flag,
            max(first_true_origin) as true_origin,
            max(first_true_dest ) as true_destination,
            max(id) as id,
            count(id) as tkts_cnt,
            (case when calculated tkts_cnt=1 then 1 else 0 end) as one_way
    from some_rando_table
    group by 1,2,3,4    ;

PADB वास्तव में क्या है?
घर्मन

ParAccel विश्लेषणात्मक डेटाबेस यह पुराना है लेकिन अच्छा है ... en.wikipedia.org/wiki/ParAccel
Wired604

लेकिन यह Postgres के बारे में एक सवाल से कैसे संबंधित है? सुनिश्चित करें कि गणना किए गए स्तंभों के समर्थन के साथ बहुत सारे DB हैं।
घुमान

खेद है कि मैं संदर्भ में वापस लाने के लिए समय नहीं लगाता .... PADB स्नातकोत्तर आधारित है!
वायर्ड 604

-6

चेक बाधा के साथ एक हल्का समाधान:

CREATE TABLE example (
    discriminator INTEGER DEFAULT 0 NOT NULL CHECK (discriminator = 0)
);

6
यह एक परिकलित स्तंभ की अवधारणा से कैसे संबंधित है? क्या आप समझाना चाहेंगे?
एरविन ब्रान्डस्टेट्टर

4
सहमत, यह सीधे संबंधित नहीं है। लेकिन एक साधारण मामले के लिए एक प्रतिस्थापन है जब आपको बस कुछ करने की ज़रूरत होती है field as 1 persisted
सिनेरियो

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

@ रोस ब्रैडबरी: सहमत हैं, लेकिन यह केवल डालने का काम करता है। यदि कोई निर्भर स्तंभ अद्यतन हो गया तो यह काम नहीं करेगा।
स्टीफन स्टीगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.