Zauważyłem MATCH SIMPLE
i MATCH FULL
, ale nie rozumiem, co oni robią. Widzę, że domyślnie jest MATCH SIMPLE
; ale jak działają inne MATCH
klauzule FOREIGN KEY
ograniczenia?
Zauważyłem MATCH SIMPLE
i MATCH FULL
, ale nie rozumiem, co oni robią. Widzę, że domyślnie jest MATCH SIMPLE
; ale jak działają inne MATCH
klauzule FOREIGN KEY
ograniczenia?
Odpowiedzi:
Sprawdź CREATE TABLE
stronę instrukcji :
Istnieją trzy typy dopasowania:
MATCH FULL
,MATCH PARTIAL
, orazMATCH SIMPLE
(co jest domyślne).MATCH FULL
nie zezwoli na to, aby jedna kolumna klucza obcego wielokolumna była pusta, chyba że wszystkie kolumny klucza obcego są puste; jeśli wszystkie są puste, wiersz nie musi mieć dopasowania w tabeli, do której się odwołuje.MATCH SIMPLE
pozwala, aby dowolna kolumna klucza obcego była pusta; jeśli którykolwiek z nich jest pusty, wiersz nie musi mieć dopasowania w tabeli, do której istnieje odwołanie.MATCH PARTIAL
nie jest jeszcze zaimplementowany. (Oczywiście,NOT NULL
można zastosować ograniczenia do kolumn odniesienia, aby zapobiec powstawaniu takich przypadków.)
Ponadto w rozdziale dotyczącym kluczy obcych :
Zwykle wiersz odniesienia nie musi spełniać ograniczenia klucza obcego, jeśli którakolwiek z jego kolumn odniesienia ma wartość NULL. Jeśli
MATCH FULL
zostanie dodany do deklaracji klucza obcego, wiersz odniesienia ucieka spełniając ograniczenie tylko wtedy, gdy wszystkie jego kolumny odwołujące są puste (tak więc zagwarantowane jest, że połączenie wartości null i innych niż null nie spowodujeMATCH FULL
ograniczenia). Jeśli nie chcesz, aby wiersze odniesienia mogły uniknąć spełnienia ograniczenia klucza obcego, zadeklaruj kolumny odniesienia jakoNOT NULL
.
I zapoznaj się z aktualną instrukcją lub wersją pasującą do twojej instalacji. Nie daj się nabrać na przestarzałe linki Google do nieaktualnych wersji.
FULL
vs SIMPLE
vsPARTIAL
Chociaż wybrana odpowiedź jest prawidłowa, jeśli jest to dla Ciebie nowość, możesz chcieć zobaczyć ją z kodem - myślę, że łatwiej jest to zrobić.
-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);
--
-- two child tables to reference it
--
CREATE TABLE t_full ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);
Logicznie, za pomocą FULL
i SIMPLE
, możemy wstawić pełne dopasowanie.
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
Problem pojawia się, gdy jedna z kolumn jest NULL
.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
Wstaw do t_full
generuje następujący błąd:
ERROR: insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1
Ok, więc co z (42,NULL)
- to część, którą zawsze uważałem za mylącą MATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
Powyższe zachowanie NIE działałoby w przypadku niezaimplementowanego MATCH PARTIAL
, który prawdopodobnie robi to, co chcesz dla indeksu złożonego, w którym kolumna znajdująca się najbardziej na prawoNULL
się wyłączona. Jednak niektórzy uważają to za metodę otwarcia pudełka Pandory na zły projekt.
MATCH FULL
wszystko musi być w pełni zgodne lub wszystkie kolumny muszą byćNULL
MATCH SIMPLE
jeśli jedno jest NULL
to ograniczenie, jest po prostu ignorowane.MATCH PARTIAL
jeśli jedno jest NULL
fakt, że nie wszystko NULL
jest częściowo uratowane przez robi coś sensownego dla celów ograniczeń.Dla potomnych, oto definicje ze specyfikacji SQL na stronie <match type>
MATCH SIMPLE
jeśli co najmniej jedna kolumna odniesienia ma wartość NULL, wówczas wiersz tabeli odniesienia przechodzi kontrolę ograniczenia. Jeśli wszystkie kolumny odwołań nie mają wartości NULL, wówczas wiersz przechodzi sprawdzenie ograniczenia wtedy i tylko wtedy, gdy istnieje wiersz tabeli, do której istnieją odwołania, która pasuje do wszystkich kolumn odniesienia.MATCH PARTIAL
: jeśli wszystkie kolumny odwołujące się mają wartość NULL, wówczas wiersz tabeli odwołującej przechodzi kontrolę ograniczenia. Jeśli co najmniej jedna kolumna odwołująca się nie ma wartości NULL, wówczas wiersz przechodzi sprawdzanie ograniczenia wtedy i tylko wtedy, gdy istnieje wiersz tabeli odwołującej się, który pasuje do wszystkich kolumn odwołujących się do wartości innej niż NULL.MATCH FULL
: jeśli wszystkie kolumny odwołujące się mają wartość NULL, wówczas wiersz tabeli odwołującej przechodzi kontrolę ograniczenia. Jeśli wszystkie kolumny odwołań nie mają wartości NULL, wówczas wiersz przechodzi sprawdzenie ograniczenia wtedy i tylko wtedy, gdy istnieje wiersz tabeli, do której istnieją odwołania, która pasuje do wszystkich kolumn odniesienia. Jeśli jakaś kolumna odniesienia ma wartość NULL, a inna kolumna odniesienia ma wartość inną niż NULL, wówczas wiersz tabeli odwołań narusza kontrolę ograniczenia.
Chociaż nie jest to specyficzne dla PostgreSQL, przykłady pokazano w PostgreSQL