foreign database-design

database-design - foreign key nullable laravel



Nullable Foreign Key mala práctica? (11)

Supongamos que tiene una tabla Órdenes con una clave externa a un ID de cliente. Ahora, supongamos que desea agregar un pedido sin un ID de cliente, (si eso debería ser posible es otra pregunta) tendría que hacer que la clave externa sea NULA ... ¿Es esa una mala práctica o preferiría trabajar con una tabla de enlaces entre Pedidos y Clientes? Aunque la relación es 1 a n, una tabla de enlace lo haría n a n. Por otro lado, con una tabla de enlaces, ya no tengo esos NULLS ...

En realidad, no habrá muchos NULL en la base de datos, porque un registro con una clave externa a NULL es solo temporalmente hasta que se agregue un cliente para el pedido.

(En mi caso, no es una orden y un cliente).

EDITAR: ¿Qué pasa con un cliente sin asignar al que enlazar?


Las columnas anulables pueden estar en 1NF a 5NF, pero no en 6NF según lo que he leído.

Solo si conoce mejor que Chris Date "lo que realmente significa la primera forma normal". Si xey son ambos anulables, y de hecho en alguna fila xey son ambos null , entonces WHERE x=y no es true . Esto demuestra más allá de toda duda razonable que nulo no es un valor (porque cualquier valor real siempre es igual a sí mismo). Y dado que el RM prescribe que "debe haber un valor en cada celda de una tabla", cualquier cosa que posiblemente contenga nulos, no es una cuestión relacional, y por lo tanto, la pregunta de 1NF ni siquiera surge.

Lo escuché argumentar que las columnas Nullable en general están rompiendo el primer grado de normalización.

Ver arriba para la razón de sonido que subyace a ese argumento.

Pero en la práctica es muy práctico.

Solo si eres inmune a los dolores de cabeza que generalmente causa en el resto del mundo. Uno de esos dolores de cabeza (y es solo menor, comparativamente a otros fenómenos null ) es el hecho de que WHERE x=y en SQL realmente significa WHERE x is not null and y is not null and x=y , sino que la mayoría de los programadores simplemente no están No estoy al tanto de ese hecho y simplemente lo leí. A veces sin ningún daño, otras veces no.

De hecho, las columnas anulables infringen una de las reglas de diseño de bases de datos más fundamentales: no combine distintos elementos de información en una columna. Los nulos hacen exactamente eso porque combinan el valor booleano "este campo está / no está realmente presente" con el valor real.


Las relaciones opcionales son definitivamente posibles en el modelo relacional.

Puede usar nulos para expresar la ausencia de una relación. Son convenientes, pero le causarán los mismos dolores de cabeza que los nulos le causan en otro lugar. Un lugar donde no causan ningún problema son las uniones. Las filas que tienen un valor nulo en la clave externa no coinciden con ninguna fila en la tabla a la que se hace referencia. Entonces abandonan una unión interna. Si realiza uniones externas, de todos modos tendrá que lidiar con nulos.

Si realmente desea evitar valores nulos (sexta forma normal), puede descomponer la tabla. Una de las dos tablas descompuestas tiene dos columnas de clave externa. Una es la clave externa opcional que tiene, y la otra es una clave externa que hace referencia a la clave principal de la tabla original. Ahora tiene que usar restricciones para evitar que la relación se convierta de muchos a muchos, si desea evitar eso.


Lo escuché argumentar que las columnas Nullable en general están rompiendo el primer grado de normalización. Pero en la práctica es muy práctico.


Los FK anulables para las relaciones opcionales de muchos a uno son totalmente buenos.


No No hay nada de malo con FK Nullable. Esto es común cuando la entidad a la que hace referencia el FK está en una relación (cero o uno) a (1 o muchos) con la tabla referenciada de la clave primaria.

Un ejemplo podría ser si tuviera una dirección física y un atributo de dirección postal (columna) en una tabla, con FK en una tabla de direcciones. Puede hacer que la dirección física sea nulable para manejar cuando la entidad solo tiene un buzón (dirección de correo) y la dirección de correo anulable para manejar cuando la dirección postal es la misma que la física (o no).


No veo nada malo con eso, es solo una relación n-1 opcional que se representará con un nulo en la clave externa. De lo contrario, si coloca su tabla de enlaces, deberá gestionar que no se convierta en una relación nn, lo que causará aún más problemas.


Sí, hay algo mal. No es una clave foránea si es anulable. Su diseño de base de datos por código. Tal vez hagas un enlace cero a no asignado. o "Sin asignar" si usa una columna de caracteres. Mantenga la integridad de sus datos al 100%.


Si solo está agregando el pedido temporalmente sin ID de cliente hasta que se haya definido un cliente, ¿no sería más sencillo agregar el cliente y el pedido en una sola transacción, eliminando así la necesidad de la entrada de clave externa NULL y evitando cualquier restricción o desencadenante? ¿Has configurado ser violado?

Normalmente esta situación se presenta en las aplicaciones web donde se detalla el orden antes de que el cliente defina quién es. Y en esas situaciones, la orden se mantiene en estado de servidor o en una cookie hasta que se proporcione todo el estado necesario para un pedido completo, en cuyo punto la orden se conserva en la base de datos.

Las claves externas NULL están bien para cosas como direcciones, como se mencionó anteriormente. Pero un campo de cliente NULL no tiene sentido para un pedido y debe estar restringido.


Siempre puede agregar una fila artificial a su tabla de clientes, algo como Id = -1 y CustomerName = ''Desconocido'' y luego en los casos en los que normalmente establecería su ID de cliente en orden NULL establecerlo en -1.

Esto le permite no tener FK anulables, pero aún así representar la falta de datos de manera apropiada (y le ahorrará a los usuarios indirectos que no saben cómo manejar NULL).


Tener la tabla de enlaces es probablemente una mejor opción. Al menos no viola la normalización BCNF (forma normal de Boyce-Codd). Sin embargo, me gustaría ser pragmático. Si tiene muy pocos de estos valores nulos y solo son temporales, creo que debe omitir la tabla de enlaces, ya que solo agrega complejidad al esquema.

En otros comentarios; usar una tabla de enlace no necesariamente lo convierte en n a n, si en la tabla de enlace usa la clave externa que apunta a su tabla de órdenes como la clave primaria en esa tabla de enlace, la relación sigue siendo 1..n. Solo puede haber una entrada en esa tabla de enlaces por pedido.


Usar NULL sería una buena manera de limpiar pedidos incompletos:

SELECT * FROM `orders` WHERE `started_time` < (UNIX_TIMESTAMP() + 900) AND `customer_id` IS NULL

Lo anterior mostraría pedidos de más de 15 minutos sin una identificación de cliente relacionada.