Serait-il considéré comme une mauvaise pratique d'avoir plusieurs FK nullables sur une table dans SQL Server

13

Sur ma structure de base de données dans SQL Server, j'ai 3 types de produits qui nécessitent des informations différentes sur la commande. Donc, j'ai créé une Customerstable et trois tables de commandes différentes: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Toutes les tables de commandes ont une relation un à plusieurs sur la Customerstable.

J'ai également une autre table qui Paymentscontient et contiendra les détails du paiement. Mais j'ai des doutes ici sur la façon de le structurer.

Étant donné que j'ai plusieurs types de produits et qu'un client peut avoir des commandes pour plusieurs produits en même temps, je dois relier ces trois tables de commande à une Paymentstable.

L'autre problème est qu'un client peut avoir une commande pour un seul type de produit. Ainsi, les colonnes FK sur la Paymentstable doivent l'être nullable.

Ma question est de savoir si ces nullablecolonnes FK seraient un casse-tête pour moi à long terme ou non? D'une manière générale, serait-il considéré comme une mauvaise pratique d'avoir des colonnes FK nullables sur une table?

tugberk
la source
2
Assurez-vous d'inclure une contrainte de vérification afin qu'au moins un de ces FK ne soit pas nul.
Damien_The_Unbeliever
3
Une clé étrangère annulable est une clé de trop.
nvogel

Réponses:

13

Je me demande pourquoi vous avez des OrdersForProductXtables.
Il est possible que le problème FK que vous avez posé puisse être conçu ...

Si ces tables ont la même structure, vous avez simplement besoin d'une ProductTypecolonne sur une OrderProducttable. Ensuite, Paymentjuste des liens vers cela avec un FK

Si la table a des structures différentes, je suppose qu'elles ont des attributs communs. Ainsi, vous pouvez avoir une OrderProducttable commune puis une table enfant spécifique par type de produit (voir ci-dessous). Encore une fois, il Paymentsuffit de créer des liens vers la table commune avec un FK

Ceci est le "modèle de super-clé / sous-type"

  • UQ1 est la "super clé" utilisée une clé étrangère sur les tables de sous-types
  • Chaque table de sous-types a un PK et un FK composites sur (OrderID, ProductType)
  • Chaque table de sous-types a une contrainte CHECK pour restreindre les types de cette table

OrderProduct

  • OrderID, PK, UQ1
  • ProductType, UQ1
  • CommonThing1
  • ...

OrderProductA

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

OrderProductB

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = B
  • ProductBThing1
  • ...
gbn
la source
4
@tugberk: Notez que vous n'aurez pas de NULLcolonnes FK avec cette approche.
ypercubeᵀᴹ
"Si ces tables ont la même structure" Elles n'ont pas la même structure.
tugberk
5

Évitez les "clés étrangères" pouvant être annulées. Ils présentent de multiples inconvénients.

La contrainte sur une ligne de référence n'est pas toujours appliquée lorsque la clé étrangère contient un null. Cependant, ce comportement par défaut n'est pas cohérent entre les différents SGBD. Certains SGBD prennent en charge les options de configuration pour modifier le comportement des clés étrangères annulables et d'autres non. Les développeurs et les utilisateurs SQL peuvent donc ne pas savoir ce que signifie réellement une contrainte de clé étrangère annulable du point de vue de l'intégrité des données. Le portage de la base de données entre les produits SGBD ou même entre différents serveurs utilisant le même produit peut donner des résultats incohérents.

Les outils de conception de base de données, les outils d'intégration et d'autres logiciels ne les prennent pas toujours correctement en charge et les résultats qu'ils produisent peuvent être erronés.

Les clés étrangères sont fréquemment utilisées dans les jointures et autres logiques de requête, aggravant les problèmes des utilisateurs qui pensent que la contrainte est en vigueur lorsqu'elle ne l'est pas ou qui ne connaissent pas la logique appliquée par votre SGBD particulier.

Certaines fonctionnalités d'optimisation de requête permettant des réécritures de requête et d'autres optimisations peuvent ne pas être disponibles lorsqu'une clé étrangère peut être annulée.

En termes logiques, une contrainte de "clé étrangère" nullable n'a pas beaucoup de sens logique. Selon la norme SQL, une telle contrainte ne peut pas être violée même si la table référencée est vide. Cela contredit l'une des justifications alléguées les plus courantes de l'utilisation d'un nul - qu'il s'agit du cas "inconnu". S'il n'y a pas de valeurs valides de X, tout X "inconnu" ne peut certainement pas être une valeur valide - et pourtant SQL le permettra.

Les clés étrangères nulles sont totalement inutiles. Vous pouvez toujours soit décomposer la clé étrangère dans une nouvelle table ou utiliser un modèle de supertype / sous-type afin que les valeurs nulles ne soient pas nécessaires. Dans un souci de simplicité et de précision, il vaut donc mieux laisser les valeurs nulles que de les insérer.

nvogel
la source
2

Je n'ai jamais entendu dire que c'était une mauvaise pratique d'utiliser des colonnes FK annulables. Ils conviennent parfaitement à une colonne qui fait référence à une autre table mais qui peut ne pas être remplie (c'est-à-dire qu'il s'agit de données facultatives).

(Pourquoi pensez-vous que ce serait un problème?)

StilesCrisis
la source
Merci! Eh bien, je ne suis pas sûr de cela, mais j'avais un projet comme celui-là il y a quelques années et je me souviens que j'avais des maux de tête sur quelque chose . Donc, je ne suis pas clair comme vous le voyez: s pourquoi j'ai posé la question.