¿Diferencias entre MATCH FULL, MATCH SIMPLE y MATCH PARTIAL?


Respuestas:


38

Consulte la CREATE TABLEpágina del manual :

Hay tres tipos de concordancia: MATCH FULL, MATCH PARTIAL, y MATCH SIMPLE (lo que es el valor por defecto). MATCH FULLno 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 SIMPLEpermite 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 PARTIALAún no está implementado. (Por supuesto, NOT NULLse 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 una MATCH 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 como NOT 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.


7

FULLvs SIMPLEvsPARTIAL

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 FULLy 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_fullgenera 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.

Definiciones simples y mnemotecnia

  • MATCH FULLtodo debe coincidir completamente , o todas las columnas deben estarNULL
  • MATCH SIMPLEsi una cosa es NULLla restricción simplemente se ignora.
  • MATCH PARTIALSi una cosa es NULLel hecho de que no todo NULLestá parcialmente rescatado por hacer algo razonable para el propósito de la restricción.

Notas de especificaciones de SQL

Para la posteridad, aquí están las definiciones de la especificación SQL en el <match type>

  • MATCH SIMPLEsi 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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.