Я помітив MATCH SIMPLE
і MATCH FULL
, але не розумію, що вони роблять. Я бачу, що за замовчуванням є MATCH SIMPLE
; але, як інші MATCH
пункти FOREIGN KEY
функції обмеження?
Я помітив MATCH SIMPLE
і MATCH FULL
, але не розумію, що вони роблять. Я бачу, що за замовчуванням є MATCH SIMPLE
; але, як інші MATCH
пункти FOREIGN KEY
функції обмеження?
Відповіді:
Перевірте CREATE TABLE
сторінку посібника :
Є три типи відповідності:
MATCH FULL
,MATCH PARTIAL
іMATCH SIMPLE
(це значення за замовчуванням).MATCH FULL
не дозволить одному стовпцю стороннього ключа з багато стовпців бути недійсним, якщо всі стовпці іноземних ключів є недійсними; якщо всі вони є недійсними, рядок не повинен мати відповідність у посилальній таблиці.MATCH SIMPLE
дозволяє будь-який стовпчик іноземного ключа бути нульовим; якщо будь-який з них є недійсним, рядок не повинен мати відповідність у посилальній таблиці.MATCH PARTIAL
ще не реалізовано. (Звичайно,NOT NULL
обмеження можуть бути застосовані до стовпців, що посилаються, щоб запобігти виникненню цих випадків.)
Також у розділі «Іноземні ключі» :
Як правило, рядки, що посилаються, не повинні задовольняти обмеження зовнішнього ключа, якщо будь-який його стовпець посилань є нульовим. Якщо
MATCH FULL
до декларації із зовнішнім ключем додано, референтний рядок виходить із задоволенням обмеження лише у тому випадку, якщо всі його посилальні стовпці є нульовими (тому гарантія поєднання нульових та ненульових значень гарантує невдачуMATCH FULL
обмеження). Якщо ви не хочете, щоб рядки, що посилаються, змогли уникнути обмеження закордонного ключа, оголосіть стовпчик (и) посилання якNOT NULL
.
Не забудьте ознайомитись із поточним посібником чи версією, що відповідає вашій установці. Не підпадайте під застарілі посилання Google на застарілі версії.
FULL
проти SIMPLE
vsPARTIAL
Хоча обрана відповідь правильна, якщо ця для вас новачка, ви, можливо, захочете побачити її з кодом - я вважаю, що простіше це зробити.
-- 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
);
Логічно, за допомогою FULL
та SIMPLE
, ми можемо вставити повну відповідність.
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
Проблема виникає, коли є один із стовпців NULL
.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
Вставка в t_full
генерує таку помилку,
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
Добре, а як же (42,NULL)
- це та частина, яку я завжди вважав заплутаною MATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
Вищенаведена поведінка НЕ працюватиме з нереалізованими MATCH PARTIAL
, що, ймовірно, робить те, що ви хочете, для складеного індексу, де NULL
виводиться найправіший стовпець . Однак деякі вважають, що це метод відкриття коробки Пандори для поганого дизайну.
MATCH FULL
все має повністю відповідати, або всі стовпці повинні бутиNULL
MATCH SIMPLE
якщо одне - NULL
обмеження, просто ігнорується.MATCH PARTIAL
якщо одна річ NULL
в тому , що не всі NULL
буде частково врятованих робити що - то осмислене з метою обмеження.Ось для нащадків, ось визначення з SQL Spec на <match type>
MATCH SIMPLE
якщо принаймні один стовпчик посилань є нульовим, то рядок таблиці посилань проходить перевірку обмежень. Якщо всі референтні стовпці не є нульовими, то рядок передає перевірку обмеження, якщо і лише якщо є рядок таблиці з посиланням, яка відповідає всім стовпцям посилань.MATCH PARTIAL
: якщо всі референтні стовпці є нульовими, то рядок таблиці посилань проходить перевірку обмежень. Якщо принаймні один стовпчик посилань не є нульовим, тоді рядок проходить перевірку обмеження, якщо і тільки якщо є рядок таблиці з посиланням, яка відповідає всім ненульовим стовпцям посилань.MATCH FULL
: якщо всі референтні стовпці є нульовими, то рядок таблиці посилань проходить перевірку обмежень. Якщо всі референтні стовпці не є нульовими, то рядок передає перевірку обмеження, якщо і лише якщо є рядок таблиці з посиланням, яка відповідає всім стовпцям посилань. Якщо якийсь стовпець реферування є нульовим, а інший стовпчик реферування - ненульовим, то рядок таблиці посилань порушує перевірку обмежень.
Хоча це не PostgreSQL, ці приклади демонструються за допомогою PostgreSQL