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

क्या PostgreSQL में सरणी तत्वों पर एक विशिष्टता बाधा हो सकती है?

धर्मी मार्ग

आप सामान्यीकरण . पर पुनर्विचार करना चाह सकते हैं आपकी स्कीमा। हर किसी के लिए यह आवश्यक नहीं है कि "सबसे सरल प्रश्न के लिए भी शामिल हों" . एक VIEW बनाएं उसके लिए।

तालिका इस तरह दिख सकती है:

CREATE TABLE hostname (
  hostname_id serial PRIMARY KEY
, host_id     int  REFERENCES host(host_id) ON UPDATE CASCADE ON DELETE CASCADE
, hostname    text UNIQUE
);

सरोगेट प्राथमिक कुंजी hostname_id वैकल्पिक है . मैं एक रखना पसंद करता हूं। आपके मामले में hostname प्राथमिक कुंजी हो सकती है। लेकिन कई ऑपरेशन सरल, छोटे integer . के साथ तेज़ होते हैं चाबी। तालिका से लिंक करने के लिए एक विदेशी कुंजी बाधा बनाएं host .
इस तरह एक दृश्य बनाएं:

CREATE VIEW v_host AS
SELECT h.*
     , array_agg(hn.hostname) AS hostnames
--   , string_agg(hn.hostname, ', ') AS hostnames  -- text instead of array
FROM   host h
JOIN   hostname hn USING (host_id)
GROUP  BY h.host_id;   -- works in v9.1+

पृष्ठ से प्रारंभ 9.1 , प्राथमिक कुंजी GROUP BY . में SELECT . में उस तालिका के सभी स्तंभों को शामिल करता है सूची। संस्करण 9.1 के लिए रिलीज़ नोट:

<ब्लॉकक्वॉट>

गैर-GROUP BY . को अनुमति दें जब प्राथमिक कुंजी GROUP BY . में निर्दिष्ट की जाती है, तो क्वेरी लक्ष्य सूची में कॉलम खंड

प्रश्न तालिका की तरह दृश्य का उपयोग कर सकते हैं। होस्टनाम खोजना बहुत होगा इस तरह से तेज़:

SELECT *
FROM   host h
JOIN   hostname hn USING (host_id)
WHERE  hn.hostname = 'foobar';

पोस्टग्रेज में 9.2+ एक बहु-स्तंभ अनुक्रमणिका और भी बेहतर होगी यदि आप एक केवल-अनुक्रमणिका स्कैन प्राप्त कर सकते हैं इसमें से:

CREATE INDEX hn_multi_idx ON hostname (hostname, host_id);

Postgres से प्रारंभ 9.3 , आप एक MATERIALIZED VIEW . का उपयोग कर सकते हैं , परिस्थितियों की अनुमति। खासकर यदि आप टेबल पर लिखने से ज्यादा बार पढ़ते हैं।

द डार्क साइड (जो आपने वास्तव में पूछा था)

यदि मैं तुम्हें नेक मार्ग के बारे में नहीं समझा सकता, तो मैं अंधेरे पक्ष में भी सहायता करूंगा। मै सहज हुं। :)

यहां एक डेमो दिया गया है कि होस्टनाम की विशिष्टता को कैसे लागू किया जाए। मैं एक टेबल hostname का उपयोग करता हूं टेबल पर होस्टनाम और ट्रिगर इकट्ठा करने के लिए host इसे अद्यतित रखने के लिए। अद्वितीय उल्लंघन अपवाद उत्पन्न करते हैं और कार्रवाई को निरस्त कर देते हैं।

CREATE TABLE host(hostnames text[]);
CREATE TABLE hostname(hostname text PRIMARY KEY);  --  pk enforces uniqueness

ट्रिगर फ़ंक्शन:

CREATE OR REPLACE FUNCTION trg_host_insupdelbef()
  RETURNS trigger AS
$func$
BEGIN
-- split UPDATE into DELETE & INSERT
IF TG_OP = 'UPDATE' THEN
   IF OLD.hostnames IS DISTINCT FROM NEW.hostnames THEN  -- keep going
   ELSE RETURN NEW;  -- exit, nothing to do
   END IF;
END IF;

IF TG_OP IN ('DELETE', 'UPDATE') THEN
   DELETE FROM hostname h
   USING  unnest(OLD.hostnames) d(x)
   WHERE  h.hostname = d.x;

   IF TG_OP = 'DELETE' THEN RETURN OLD;  -- exit, we are done
   END IF;
END IF;

-- control only reaches here for INSERT or UPDATE (with actual changes)
INSERT INTO hostname(hostname)
SELECT h
FROM   unnest(NEW.hostnames) h;

RETURN NEW;
END
$func$ LANGUAGE plpgsql;

ट्रिगर:

CREATE TRIGGER host_insupdelbef
BEFORE INSERT OR DELETE OR UPDATE OF hostnames ON host
FOR EACH ROW EXECUTE PROCEDURE trg_host_insupdelbef();

एसक्यूएल फिडल टेस्ट रन के साथ।

GIN अनुक्रमणिका . का उपयोग करें सरणी कॉलम पर host.hostnames और सरणी ऑपरेटर इसके साथ काम करने के लिए:

  • मेरी PostgreSQL सरणी अनुक्रमणिका का उपयोग क्यों नहीं हो रहा है (रेल 4)?
  • जांचें कि पोस्टग्रेज एरे में दिए गए मानों में से कोई एक सरणी मौजूद है या नहीं


  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. दी गई तिथि में व्यावसायिक दिनों की संख्या कैसे जोड़ें

  3. PostgreSQL को कभी-कभी खराब क्वेरी प्लान चुनने से रोकें

  4. Django में PostgreSQL डेटाबेस कैसे सेट करें?

  5. मैं विंडोज़ पर पोस्टग्रेएसक्यूएल कैसे शुरू कर सकता हूं?