Відмінності між ПОВНОЮ МАТЧУ, ПРОСТОЮ МАТЧУ І ЧАСТИНОЮ МАТЧУ?


Відповіді:


38

Перевірте CREATE TABLEсторінку посібника :

Є три типи відповідності: MATCH FULL, MATCH PARTIALі MATCH SIMPLE (це значення за замовчуванням). MATCH FULLне дозволить одному стовпцю стороннього ключа з багато стовпців бути недійсним, якщо всі стовпці іноземних ключів є недійсними; якщо всі вони є недійсними, рядок не повинен мати відповідність у посилальній таблиці. MATCH SIMPLEдозволяє будь-який стовпчик іноземного ключа бути нульовим; якщо будь-який з них є недійсним, рядок не повинен мати відповідність у посилальній таблиці. MATCH PARTIALще не реалізовано. (Звичайно, NOT NULLобмеження можуть бути застосовані до стовпців, що посилаються, щоб запобігти виникненню цих випадків.)

Також у розділі «Іноземні ключі» :

Як правило, рядки, що посилаються, не повинні задовольняти обмеження зовнішнього ключа, якщо будь-який його стовпець посилань є нульовим. Якщо MATCH FULL до декларації із зовнішнім ключем додано, референтний рядок виходить із задоволенням обмеження лише у тому випадку, якщо всі його посилальні стовпці є нульовими (тому гарантія поєднання нульових та ненульових значень гарантує невдачу MATCH FULL обмеження). Якщо ви не хочете, щоб рядки, що посилаються, змогли уникнути обмеження закордонного ключа, оголосіть стовпчик (и) посилання як NOT NULL.

Не забудьте ознайомитись із поточним посібником чи версією, що відповідає вашій установці. Не підпадайте під застарілі посилання Google на застарілі версії.


7

FULLпроти SIMPLEvsPARTIAL

Хоча обрана відповідь правильна, якщо ця для вас новачка, ви, можливо, захочете побачити її з кодом - я вважаю, що простіше це зробити.

-- 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

Ось для нащадків, ось визначення з SQL Spec на <match type>

  • MATCH SIMPLEякщо принаймні один стовпчик посилань є нульовим, то рядок таблиці посилань проходить перевірку обмежень. Якщо всі референтні стовпці не є нульовими, то рядок передає перевірку обмеження, якщо і лише якщо є рядок таблиці з посиланням, яка відповідає всім стовпцям посилань.
  • MATCH PARTIAL: якщо всі референтні стовпці є нульовими, то рядок таблиці посилань проходить перевірку обмежень. Якщо принаймні один стовпчик посилань не є нульовим, тоді рядок проходить перевірку обмеження, якщо і тільки якщо є рядок таблиці з посиланням, яка відповідає всім ненульовим стовпцям посилань.
  • MATCH FULL: якщо всі референтні стовпці є нульовими, то рядок таблиці посилань проходить перевірку обмежень. Якщо всі референтні стовпці не є нульовими, то рядок передає перевірку обмеження, якщо і лише якщо є рядок таблиці з посиланням, яка відповідає всім стовпцям посилань. Якщо якийсь стовпець реферування є нульовим, а інший стовпчик реферування - ненульовим, то рядок таблиці посилань порушує перевірку обмежень.

Хоча це не PostgreSQL, ці приклади демонструються за допомогою PostgreSQL

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.