He notado una MATCH SIMPLE
y MATCH FULL
, pero no entiendo lo que hacen. Veo por defecto es MATCH SIMPLE
; pero, ¿cómo funcionan las otras MATCH
cláusulas de la FOREIGN KEY
restricción?
fuente
He notado una MATCH SIMPLE
y MATCH FULL
, pero no entiendo lo que hacen. Veo por defecto es MATCH SIMPLE
; pero, ¿cómo funcionan las otras MATCH
cláusulas de la FOREIGN KEY
restricción?
Consulte la CREATE TABLE
página del manual :
Hay tres tipos de concordancia:
MATCH FULL
,MATCH PARTIAL
, yMATCH SIMPLE
(lo que es el valor por defecto).MATCH FULL
no permitirá que una columna de una clave externa de varias columnas sea nula a menos que todas las columnas de clave externa sean nulas; si todos son nulos, no se requiere que la fila tenga una coincidencia en la tabla referenciada.MATCH SIMPLE
permite que cualquiera de las columnas de clave externa sea nula; Si alguno de ellos es nulo, no es necesario que la fila tenga una coincidencia en la tabla referenciada.MATCH PARTIAL
Aún no está implementado. (Por supuesto,NOT NULL
se pueden aplicar restricciones a las columnas de referencia para evitar que surjan estos casos).
Además, en el capítulo sobre claves extranjeras :
Normalmente, una fila de referencia no necesita satisfacer la restricción de clave externa si alguna de sus columnas de referencia es nula. Si
MATCH FULL
se agrega a la declaración de clave externa, una fila de referencia se escapa satisfaciendo la restricción solo si todas sus columnas de referencia son nulas (por lo que se garantiza que una combinación de valores nulos y no nulos fallará en unaMATCH FULL
restricción). Si no desea que las filas de referencia puedan evitar satisfacer la restricción de clave externa, declare las columnas de referencia comoNOT NULL
.
Y asegúrese de consultar el manual actual o la versión que coincida con su instalación. No caigas en los enlaces obsoletos de Google con versiones desactualizadas.
FULL
vs SIMPLE
vsPARTIAL
Si bien la respuesta elegida es correcta, si esto es nuevo para usted, es posible que desee verlo con código; creo que es más fácil asimilarlo de esa manera.
-- 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
);
Lógicamente, con FULL
y SIMPLE
, podemos insertar una coincidencia completa.
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
El problema surge cuando una de las columnas es NULL
.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
La inserción en t_full
genera el siguiente error,
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, entonces, ¿qué pasa (42,NULL)
? Esta es la parte que siempre me pareció confusa MATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
El comportamiento anterior NO funcionaría con los no implementados MATCH PARTIAL
, lo que probablemente haga lo que desea para un índice compuesto donde la columna más a la derecha estáNULL
. Sin embargo, algunas personas lo ven como un método para abrir la caja de Pandora al mal diseño.
MATCH FULL
todo debe coincidir completamente , o todas las columnas deben estarNULL
MATCH SIMPLE
si una cosa es NULL
la restricción simplemente se ignora.MATCH PARTIAL
Si una cosa es NULL
el hecho de que no todo NULL
está parcialmente rescatado por hacer algo razonable para el propósito de la restricción.Para la posteridad, aquí están las definiciones de la especificación SQL en el <match type>
MATCH SIMPLE
si al menos una columna de referencia es nula, la fila de la tabla de referencia pasa la verificación de restricción. Si todas las columnas de referencia no son nulas, entonces la fila pasa la verificación de restricción si y solo si hay una fila de la tabla referenciada que coincida con todas las columnas de referencia.MATCH PARTIAL
: si todas las columnas de referencia son nulas, entonces la fila de la tabla de referencia pasa la verificación de restricción. Si al menos una columna de referencia no es nula, la fila pasa la verificación de restricción si y solo si hay una fila de la tabla referenciada que coincida con todas las columnas de referencia no nula.MATCH FULL
: si todas las columnas de referencia son nulas, entonces la fila de la tabla de referencia pasa la verificación de restricción. Si todas las columnas de referencia no son nulas, entonces la fila pasa la verificación de restricción si y solo si hay una fila de la tabla referenciada que coincida con todas las columnas de referencia. Si alguna columna de referencia es nula y otra columna de referencia no es nula, entonces la fila de la tabla de referencia viola la verificación de restricción.
Si bien esto no es específico de PostgreSQL, estos ejemplos se demuestran con PostgreSQL