¿Pueden las columnas de la tabla con una clave externa ser NULL?
Tengo una tabla que tiene varias columnas de ID de otras tablas.
Quiero una clave externa para forzar la integridad sólo si pongo datos allí. Si hago una actualización más adelante para completar esa columna, entonces también debería verificar la restricción.
(Esto probablemente depende del servidor de la base de datos, estoy usando el tipo de tabla MySQL e InnoDB)
Creo que esta es una expectativa razonable, pero corríjanme si me equivoco.
Sí, puede aplicar la restricción solo cuando el valor no sea NULL. Esto se puede comprobar fácilmente con el siguiente ejemplo:
CREATE DATABASE t;
USE t;
CREATE TABLE parent (id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (id INT NULL,
parent_id INT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=INNODB;
INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)
INSERT INTO child (id, parent_id) VALUES (2, 1);
-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key
-- constraint fails (`t/child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY
-- (`parent_id`) REFERENCES `parent` (`id`))
La primera inserción pasará porque insertamos un NULL en el archivo parent_id
. La segunda inserción falla debido a la restricción de clave externa, ya que intentamos insertar un valor que no existe en la parent
tabla.
Descubrí que al insertar, los valores de la columna nula debían declararse específicamente como NULL; de lo contrario, obtendría un error de infracción de restricción (en lugar de una cadena vacía).
Sí, eso funcionará como esperas. Desafortunadamente, parece que tengo problemas para encontrar una declaración explícita de esto en el manual de MySQL .
Las claves externas significan que el valor debe existir en la otra tabla. NULL se refiere a la ausencia de valor, por lo que cuando establece una columna en NULL, no tendría sentido intentar imponer restricciones a eso.
Sí, el valor puede ser NULL, pero debes ser explícito. He experimentado esta misma situación antes y es fácil olvidar POR QUÉ sucede esto, por lo que lleva un poco de tiempo recordar lo que se debe hacer.
Si los datos enviados se convierten o interpretan como una cadena vacía, fallará. Sin embargo, al establecer explícitamente el valor en NULL al INSERTAR o ACTUALIZAR, estará listo.
Pero esto es lo divertido de programar, ¿no? ¡Creando nuestros propios problemas y luego solucionándolos! ¡Salud!