दुर्भाग्य से, आपका पिछला प्रश्न ।
यह काम करना चाहिए:
-
एक अनावश्यक ध्वज जोड़ें
is_published
Child
. को टेबल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;