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

एक ट्रिगर बनाने की आवश्यकता है जो सम्मिलन के बाद किसी तालिका में मान बढ़ाता है

सारांश मान को बनाए रखना मुश्किल है - डेडलॉक की संभावना बनाना आसान है आपका कार्यक्रम।

यदि आपको वास्तव में ऐसा करना है, क्योंकि आप जानते हैं कि आपको प्रदर्शन की समस्याएँ होंगी अन्यथा (जैसे सैकड़ों या अधिक में nhunts), तो बेहतर होगा कि nhunts के लिए एक अलग सारांश तालिका बनाई जाए, कुछ इस तरह:

CREATE TABLE hunts_summary
(
    id_hs bigserial primary key,
    id_h integer NOT NULL,
    nhunts integer NOT NULL
);
CREATE INDEX hunts_summary_id_h_idx on hunts_summary(id_h);

शिकार के लिए ट्रिगर:

  • प्रत्येक जोड़ी गई, हटाई गई, अपडेट की गई पंक्ति के लिए चलती है;
  • एक पंक्ति जोड़ता है (id_h, nhunts) = (NEW.id_h, 1) प्रत्येक डालने पर;
  • एक पंक्ति जोड़ता है (id_h, nhunts) = (OLD.id_h, -1) प्रत्येक डिलीट पर;
  • उपरोक्त दोनों अपडेट पर जो id_h को बदलता है ।

चूंकि ट्रिगर केवल नई पंक्तियों को जोड़ देगा, यह मौजूदा पंक्तियों को लॉक नहीं करता है और इसलिए यह गतिरोध नहीं कर सकता है।

लेकिन यह पर्याप्त नहीं है - जैसा कि ऊपर वर्णित सारांश तालिका शिकार तालिका की तुलना में पंक्तियों को तेज़ी से या तेज़ी से बढ़ेगी, इसलिए यह बहुत उपयोगी नहीं है। इसलिए हमें मौजूदा पंक्तियों को समय-समय पर मर्ज करने के लिए कुछ तरीके जोड़ने की जरूरत है - किसी तरह बदलने के लिए:

id_h nhunts
1    1
1    1
2    1
2    -1
1    1
1    -1
2    1
1    1
2    1

प्रति:

id_h nhunts
1    3
2    2

यह प्रत्येक ट्रिगर आमंत्रण पर नहीं चलना चाहिए, क्योंकि यह तब काफी धीमा होगा, लेकिन यह यादृच्छिक रूप से चल सकता है - उदाहरण के लिए यादृच्छिक रूप से प्रत्येक 1/1024 वें आमंत्रण। अन्यथा संभावित गतिरोध से बचने के लिए, यह फ़ंक्शन पहले से लॉक की गई पंक्तियों को छूने से बचने के लिए "स्किप लॉक" कीवर्ड का उपयोग करेगा।

ऐसा ट्रिगर कुछ इस तरह दिखेगा:

create or replace function hunts_maintain() returns trigger
as $hunts_maintain$
        begin
                if (tg_op = 'INSERT') then
                        insert into hunts_summary(id_h, nhunts)
                                values (NEW.id_h, 1);
                elsif (tg_op = 'DELETE') then
                        insert into hunts_summary(id_h, nhunts)
                                values (OLD.id_h, -1);
                elsif (tg_op = 'UPDATE' and NEW.id_h!=OLD.id_h) then
                        insert into hunts_summary(id_h, nhunts)
                                values (OLD.id_h, -1), (NEW.id_h, 1);
                end if;

                if (random()*1024 < 1) then
                        with deleted_ids as (
                                select id_hs from hunts_summary for update skip locked
                        ),
                        deleted_nhunts as (
                                delete from hunts_summary where id_hs in (select id_hs from deleted_ids) returning id_h, nhunts
                        )
                        insert into hunts_summary (id_h, nhunts) select id_h, sum(nhunts) from deleted_nhunts group by id_h;
                end if;

                return NEW;
        end;
$hunts_maintain$ language plpgsql;

create trigger hunts_maintain
        after insert or update or delete on hunts
        for each row execute procedure hunts_maintain();

मेरे लैपटॉप पर ट्रिगर इतनी तेजी से चलता है कि 45 के दशक में तालिका में 1M पंक्तियों को सम्मिलित करता है।

नीचे दिया गया यह दृश्य सारांश से वर्तमान ननहंट को निकालना आसान बना देगा। इसे क्वेरी करने में एक छोटी संख्या या एमएस लगेगा, भले ही हंट्स टेबल अरबों में हो:

create or replace view hunts_summary_view as
        select id_h, sum(nhunts) as nhunts
        from hunts_summary
        group by id_h;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कैसे इंगित करें कि एक भौतिक दृश्य बनाते समय एक स्तंभ अशक्त नहीं है?

  2. postgresql:INSERT INTO ... (चुनें * ...)

  3. TemplateSyntaxError:रेंडर करते समय इम्पोर्ट एरर पकड़ा गया:नाम के बर्तन आयात नहीं कर सकते

  4. पोस्टग्रेज यूनिक्स डोमेन सॉकेट 5432 पर सर्वर से कनेक्ट नहीं हो सकता है

  5. Paramiko में Windows SSH सर्वर पर कमांड (pg_dump) निष्पादित करने से पहले पर्यावरण चर (PGPASSWORD) सेट करें