Unterschiede zwischen MATCH FULL, MATCH SIMPLE und MATCH PARTIAL?

29

Ich habe ein MATCH SIMPLEund bemerkt MATCH FULL, aber ich verstehe nicht, was sie tun. Ich sehe Standard ist MATCH SIMPLE; Aber wie funktionieren die anderen MATCHKlauseln der FOREIGN KEYEinschränkung?

Evan Carroll
quelle

Antworten:

38

Überprüfen Sie die CREATE TABLESeite des Handbuchs :

Es gibt drei Spielarten: MATCH FULL, MATCH PARTIAL, und MATCH SIMPLE (das ist die Standardeinstellung). MATCH FULLErlaubt nicht, dass eine Spalte eines mehrspaltigen Fremdschlüssels null ist, es sei denn, alle Fremdschlüsselspalten sind null. Wenn sie alle null sind, muss die Zeile in der referenzierten Tabelle nicht übereinstimmen. MATCH SIMPLEErmöglicht, dass eine der Fremdschlüsselspalten null ist. Wenn einer von ihnen null ist, muss die Zeile in der referenzierten Tabelle nicht übereinstimmen. MATCH PARTIAList noch nicht implementiert. (Natürlich können NOT NULLEinschränkungen auf die referenzierenden Spalten angewendet werden, um das Auftreten dieser Fälle zu verhindern.)

Im Kapitel über Fremdschlüssel :

Normalerweise muss eine referenzierende Zeile die Fremdschlüsseleinschränkung nicht erfüllen, wenn eine ihrer referenzierenden Spalten null ist. Wenn MATCH FULL der Fremdschlüsseldeklaration hinzugefügt wird, wird eine Verweiszeile nur dann ausgeblendet, wenn alle ihre Verweisspalten null sind MATCH FULL . Wenn Sie nicht möchten, dass referenzierende Zeilen die Fremdschlüsseleinschränkung nicht erfüllen, deklarieren Sie die referenzierenden Spalten als NOT NULL.

Beachten Sie auch das aktuelle Handbuch oder die Version, die Ihrer Installation entspricht. Fallen Sie nicht auf veraltete Google-Links zu veralteten Versionen herein.

Erwin Brandstetter
quelle
7

FULLvs SIMPLEvsPARTIAL

Die gewählte Antwort ist zwar richtig, aber wenn dies für Sie neu ist, möchten Sie sie möglicherweise mit Code anzeigen - ich denke, es ist einfacher, auf diese Weise zu gründen.

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

Logischerweise können wir mit FULLund SIMPLEeine vollständige Übereinstimmung einfügen.

-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);

Das Problem kommt, wenn eine der Spalten ist NULL.

-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);

-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);

Das Einfügen in t_fullerzeugt den folgenden Fehler:

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, was ist mit (42,NULL)- das ist der Teil, den ich immer verwirrend fand MATCH SIMPLE,

-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);

Das obige Verhalten würde NICHT mit dem nicht implementierten funktionieren MATCH PARTIAL, was wahrscheinlich das tut, was Sie für einen zusammengesetzten Index wollen, bei dem die am weitesten rechts stehende Spalte NULLausgeblendet ist. Einige Leute betrachten dies jedoch als eine Methode, die Büchse einer Pandora für schlechtes Design zu öffnen.

Einfache Definitionen & Mnemonik

  • MATCH FULLAlles muss vollständig übereinstimmen, oder alle Spalten müssen übereinstimmenNULL
  • MATCH SIMPLEWenn eine Sache NULLdie Einschränkung ist, wird sie einfach ignoriert.
  • MATCH PARTIALwenn eine Sache ist NULLdie Tatsache , dass nicht alles NULLwird teilweise durch etwas zu tun , sinnvoll für den Zweck der Beschränkung geborgen.

SQL Spec Notes

Für die Nachwelt finden Sie hier die Definitionen aus der SQL-Spezifikation auf der <match type>

  • MATCH SIMPLEWenn mindestens eine referenzierende Spalte null ist, besteht die Zeile der referenzierenden Tabelle die Einschränkungsprüfung. Wenn nicht alle referenzierenden Spalten null sind, besteht die Zeile die Einschränkungsprüfung nur dann, wenn eine Zeile der referenzierten Tabelle vorhanden ist, die mit allen referenzierenden Spalten übereinstimmt.
  • MATCH PARTIAL: Wenn alle referenzierenden Spalten null sind, besteht die Zeile der referenzierenden Tabelle die Einschränkungsprüfung. Wenn mindestens eine referenzierende Spalte nicht null ist, besteht die Zeile die Einschränkungsprüfung nur dann, wenn eine Zeile der referenzierten Tabelle vorhanden ist, die mit allen referenzierenden Spalten übereinstimmt, die nicht null sind.
  • MATCH FULL: Wenn alle referenzierenden Spalten null sind, besteht die Zeile der referenzierenden Tabelle die Einschränkungsprüfung. Wenn nicht alle referenzierenden Spalten null sind, besteht die Zeile die Einschränkungsprüfung nur dann, wenn eine Zeile der referenzierten Tabelle vorhanden ist, die mit allen referenzierenden Spalten übereinstimmt. Wenn eine Referenzierungsspalte null und eine andere Referenzierungsspalte nicht null ist, verletzt die Zeile der Referenzierungstabelle die Einschränkungsprüfung.

Obwohl dies nicht PostgreSQL-spezifisch ist, werden diese Beispiele mit PostgreSQL demonstriert

Evan Carroll
quelle