दुर्भाग्य से, आपका पिछला प्रश्न ।
यह काम करना चाहिए:
-
एक अनावश्यक ध्वज जोड़ें
is_publishedChild. को टेबलALTER TABLE child ADD column is_published boolean NOT NULL;इसे
DEFAULT FALSEबनाएं या जो कुछ भी सम्मिलित करते समय आपके पास आमतौर पर पैरेंट कॉलम में होता है।
इसेNOT NULLहोना चाहिएNULL. के साथ एक खामी से बचने के लिए मान और डिफ़ॉल्टMATCH SIMPLEविदेशी कुंजियों में व्यवहार:
दो-कॉलम विदेशी कुंजी बाधा केवल तभी जब तीसरा कॉलम न्यूल न हो -
parent(parent_id, is_published)पर एक (प्रतीत होता है व्यर्थ, अभी तक) अद्वितीय बाधा जोड़ेंALTER TABLE parent ADD CONSTRAINT parent_fk_uni UNIQUE (parent_id, is_published);चूंकि
parent_idप्राथमिक कुंजी है, संयोजन किसी भी तरह से अद्वितीय होगा। लेकिन यह निम्न fk बाधा के लिए आवश्यक है। -
parent(parent_id). को संदर्भित करने के बजाय एक साधारण विदेशी कुंजी बाधा ,(parent_id, is_published)पर एक बहु-स्तंभ विदेशी कुंजी बनाएंON UPDATE CASCADE. के साथ .
इस तरह,child.is_published. की स्थिति सिस्टम द्वारा स्वचालित रूप से बनाए रखा और लागू किया जाता है और आप कस्टम ट्रिगर्स के साथ कार्यान्वित कर सकते हैं:ALTER TABLE child ADD CONSTRAINT child_special_fkey FOREIGN KEY (parent_id, is_published) REFERENCES parent (parent_id, is_published) ON UPDATE CASCADE; -
फिर एक आंशिक UNIQUE अनुक्रमणिका जोड़ें आपके पिछले उत्तर की तरह।
CREATE UNIQUE INDEX child_txt_is_published_idx ON child (text) WHERE is_published;
बेशक, child . में पंक्तियाँ डालने पर तालिका आप parent.is_published . की वर्तमान स्थिति का उपयोग करने के लिए बाध्य हैं अभी व। लेकिन यही बात है:संदर्भात्मक अखंडता को लागू करने के लिए।
पूर्ण स्कीमा
या, मौजूदा स्कीमा को अनुकूलित करने के बजाय, यहाँ पूरा लेआउट दिया गया है:
CREATE TABLE parent(
parent_id serial PRIMARY KEY
, is_published bool NOT NULL DEFAULT FALSE
--, more columns ...
, UNIQUE (parent_id, is_published) -- required for fk
);
CREATE TABLE child (
child_id serial PRIMARY KEY
, parent_id integer NOT NULL
, is_published bool NOT NULL DEFAULT FALSE
, txt text
, FOREIGN KEY (parent_id, is_published)
REFERENCES parent (parent_id, is_published) ON UPDATE CASCADE
);
CREATE UNIQUE INDEX child_txt_is_published_idx ON child (text)
WHERE is_published;