¿Se consideraría una mala práctica tener múltiples FK anulables en una tabla en SQL Server

13

En mi estructura de base de datos en SQL Server, tengo 3 tipos de productos que requieren información diferente sobre el pedido. Por lo tanto, he creado una Customersmesa y tres mesas diferentes órdenes: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Todas las tablas de pedidos tienen una relación de uno a muchos en la Customerstabla

También tengo otra tabla que Paymentscontiene y mantendrá los detalles de pago dentro. Pero tengo dudas aquí sobre cómo estructurarlo.

Como tengo varios tipos de productos y un cliente puede tener pedidos de varios productos al mismo tiempo, necesito relacionar esas tres tablas de pedidos con la Paymentstabla.

El otro problema es que un cliente puede tener un pedido para un solo tipo de producto. Entonces, las columnas FK en la Paymentstabla deben ser nullable.

Mi pregunta es si esas nullablecolumnas FK serían un dolor de cabeza para mí a largo plazo o no. En términos generales, ¿se consideraría una mala práctica tener columnas FK anulables en una tabla?

tugberk
fuente
2
Asegúrese de incluir una restricción de verificación para que al menos uno de esos FK no sea nulo.
Damien_The_Unbeliever
3
Una clave externa anulable es demasiada.
nvogel

Respuestas:

13

Me preguntaría por qué tienes OrdersForProductXtablas.
Es posible que el problema de FK que has preguntado pueda ser diseñado ...

Si estas tablas tienen la misma estructura, simplemente necesita una ProductTypecolumna en alguna OrderProducttabla. Luego Paymentsolo se vincula a eso con un FK

Si la tabla tiene estructuras diferentes, supongo que tienen algunos atributos comunes. Por lo tanto, puede tener una OrderProducttabla común y luego una tabla secundaria específica por tipo de producto (ver más abajo). Una vez más, Paymentsolo se vincula a la tabla común con un FK

Este es el "patrón de superclave / subtipo"

  • UQ1 es la "superclave" que utiliza una clave foránea en las tablas de subtipo
  • Cada tabla de subtipo tiene un PK y FK compuestos en (OrderID, ProductType)
  • Cada tabla de subtipo tiene una restricción CHECK para restringir los tipos en esa tabla

OrderProduct

  • OrderID, PK, UQ1
  • Tipo de producto, UQ1
  • CommonThing1
  • ...

OrderProductA

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = A
  • ProductAThing1
  • ...

OrderProductB

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = B
  • ProductoBThing1
  • ...
gbn
fuente
44
@tugberk: Tenga en cuenta que no tendrá NULLcolumnas FK con este enfoque.
ypercubeᵀᴹ
"Si estas tablas tienen la misma estructura" No tienen la misma estructura.
tugberk
5

Evite las "claves foráneas" anulables. Tienen múltiples desventajas.

La restricción en una fila de referencia no siempre se aplica cuando la clave externa contiene un valor nulo. Sin embargo, ese comportamiento predeterminado no es coherente entre diferentes DBMS. Algunos DBMS admiten opciones de configuración para cambiar el comportamiento de las claves foráneas anulables y otras no. Por lo tanto, los desarrolladores y usuarios de SQL pueden no tener claro qué significa realmente una restricción de clave externa anulable desde una perspectiva de integridad de datos. Portar la base de datos entre productos DBMS o incluso entre diferentes servidores que usan el mismo producto podría dar resultados inconsistentes.

Las herramientas de diseño de bases de datos, las herramientas de integración y otro software no siempre las admiten correctamente y los resultados que producen pueden ser incorrectos.

Las claves externas se usan con frecuencia en combinaciones y otras lógicas de consulta, lo que agrava los problemas para los usuarios que piensan que la restricción está vigente cuando no lo es o que no conocen la lógica que aplica su DBMS en particular.

Algunas funciones de optimización de consultas que permiten reescrituras de consultas y otras optimizaciones pueden no estar disponibles cuando una clave externa es anulable.

En términos lógicos, una restricción de "clave externa" anulable no tiene mucho sentido lógico. De acuerdo con el estándar SQL, tal restricción no puede ser violada incluso si la tabla a la que se hace referencia está vacía. Eso contradice una de las presuntas justificaciones más comunes para usar un valor nulo: que representa el caso "desconocido". Si no hay valores válidos de X, entonces cualquier X "desconocido" ciertamente no puede ser un valor válido, y aun así SQL lo permitirá.

Las claves externas anulables son completamente innecesarias. Siempre puede descomponer la clave externa en una nueva tabla o usar un patrón de supertipo / subtipo para que no se necesiten valores nulos. En aras de la simplicidad y la precisión, por lo tanto, es mejor dejar los nulos fuera que introducirlos.

nvogel
fuente
2

Nunca escuché que considerara una mala práctica usar columnas FK anulables. Son ideales para una columna que hace referencia a otra tabla pero puede que no se complete (es decir, son datos opcionales).

(¿Por qué crees que sería un problema?)

StilesCrisis
fuente
¡Gracias! Bueno, no estoy muy seguro de eso, pero tuve un proyecto como ese hace un par de años y recuerdo que me dolía la cabeza por algo . Por lo tanto, no estoy claro, como puede ver: s por qué hice la pregunta.