Bohužel neexistuje řešení tak jednoduché a čisté jako pro vaše předchozí otázka .
Toto by mělo fungovat:
-
Přidejte nadbytečný příznak
is_published
naChild
tabulkaALTER TABLE child ADD column is_published boolean NOT NULL;
Nastavte jej na
DEFAULT FALSE
nebo cokoli, co obvykle máte v nadřazených sloupcích při vkládání.
Musí býtNOT NULL
abyste se vyhnuli mezeře sNULL
hodnoty a výchozíMATCH SIMPLE
chování v cizích klíčích:
Dvousloupcové omezení cizího klíče pouze v případě, že třetí sloupec NENÍ NULL -
Přidejte (zdánlivě nesmyslné, ale přesto) jedinečné omezení na
parent(parent_id, is_published)
ALTER TABLE parent ADD CONSTRAINT parent_fk_uni UNIQUE (parent_id, is_published);
Od
parent_id
je primární klíč, kombinace by byla jedinečná v obou směrech. Ale to je vyžadováno pro následující omezení fk. -
Místo odkazování na
parent(parent_id)
s jednoduchým omezení cizího klíče , vytvořte cizí klíč s více sloupci na(parent_id, is_published)
pomocíON UPDATE CASCADE
.
Tímto způsobem bude stavchild.is_published
je udržován a vynucován systémem automaticky a spolehlivěji, než byste mohli implementovat pomocí vlastních spouštěčů:ALTER TABLE child ADD CONSTRAINT child_special_fkey FOREIGN KEY (parent_id, is_published) REFERENCES parent (parent_id, is_published) ON UPDATE CASCADE;
-
Poté přidejte částečný UNIQUE index jako ve vaší předchozí odpovědi.
CREATE UNIQUE INDEX child_txt_is_published_idx ON child (text) WHERE is_published;
Samozřejmě při vkládání řádků do child
tabulky jste nuceni použít aktuální stav parent.is_published
Nyní. Ale o to jde:prosadit referenční integritu.
Úplné schéma
Nebo namísto přizpůsobení existujícího schématu zde je kompletní rozvržení:
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;