Vereenvoudig bouwen op MATCH SIMPLE
gedrag van fk-beperkingen
Als ten minste één kolom met een buitenlandse beperking met meerdere kolommen met standaard MATCH SIMPLE
gedrag is NULL
, wordt de beperking niet gehandhaafd. U kunt daarop voortbouwen om uw ontwerp grotendeels te vereenvoudigen.
CREATE SCHEMA test;
CREATE TABLE test.status(
status_id integer PRIMARY KEY
,sub bool NOT NULL DEFAULT FALSE -- TRUE .. *can* be sub-status
,UNIQUE (sub, status_id)
);
CREATE TABLE test.entity(
entity_id integer PRIMARY KEY
,status_id integer REFERENCES test.status -- can reference all statuses
,sub bool -- see examples below
,additional_col1 text -- should be NULL for main entities
,additional_col2 text -- should be NULL for main entities
,FOREIGN KEY (sub, status_id) REFERENCES test.status(sub, status_id)
MATCH SIMPLE ON UPDATE CASCADE -- optionally enforce sub-status
);
Het is erg goedkoop om enkele extra NULL-kolommen op te slaan (voor hoofdentiteiten):
BTW, per documentatie:
Demo-gegevens:
INSERT INTO test.status VALUES
(1, TRUE)
, (2, TRUE)
, (3, FALSE); -- not valid for sub-entities
INSERT INTO test.entity(entity_id, status_id, sub) VALUES
(11, 1, TRUE) -- sub-entity (can be main, UPDATES to status.sub cascaded)
, (13, 3, FALSE) -- entity (cannot be sub, UPDATES to status.sub cascaded)
, (14, 2, NULL) -- entity (can be sub, UPDATES to status.sub NOT cascaded)
, (15, 3, NULL) -- entity (cannot be sub, UPDATES to status.sub NOT cascaded)
SQL Fiddle (inclusief je tests).
Alternatief met enkele FK
Een andere optie zou zijn om alle combinaties van (status_id, sub)
. in te voeren in de status
tabel (er kunnen er maar 2 zijn per status_id
) en hebben slechts één fk-beperking:
CREATE TABLE test.status(
status_id integer
,sub bool DEFAULT FALSE
,PRIMARY KEY (status_id, sub)
);
CREATE TABLE test.entity(
entity_id integer PRIMARY KEY
,status_id integer NOT NULL -- cannot be NULL in this case
,sub bool NOT NULL -- cannot be NULL in this case
,additional_col1 text
,additional_col2 text
,FOREIGN KEY (status_id, sub) REFERENCES test.status
MATCH SIMPLE ON UPDATE CASCADE -- optionally enforce sub-status
);
INSERT INTO test.status VALUES
(1, TRUE) -- can be sub ...
(1, FALSE) -- ... and main
, (2, TRUE)
, (2, FALSE)
, (3, FALSE); -- only main
enz.
Gerelateerde antwoorden:
- MATCH VOL vs MATCH SIMPLE
- Twee-koloms refererende sleutelbeperking alleen als de derde kolom NIET NULL is
- Uniqueness validatie in database wanneer validatie een voorwaarde heeft op een andere tabel
Bewaar alle tafels
Als je alle vier de tabellen nodig hebt om de een of andere reden die niet in de vraag staat, overweeg dan deze gedetailleerde oplossing voor een zeer vergelijkbare vraag op dba.SE:
Overerving
... is misschien een andere optie voor wat je beschrijft. Als je kunt leven met enkele belangrijke beperkingen . Gerelateerd antwoord: