Dans notre projet de base de données, nous avons une table Sale
qui a une clé primaire et deux clés étrangères exclusives: Vehicle_ID
et Piece_ID
. Par exemple, si nous vendons un véhicule, nous avons besoin de Vehicle_ID
comme clé étrangère, mais pas de Piece_ID
. Peut-on mettre NULL à Piece_ID
, une clé étrangère peut-elle être nulle? Ou est-il possible de faire ce travail?
Merci.
La colonne (ou les colonnes) d'une clé primaire doit être NOT NULL. Un enregistrement ne peut pas être identifié de manière unique par un NULL. Par conséquent, les colonnes ID situées à l'extrémité référencée de la clé étrangère doivent être définies comme NOT NULL.
Cependant, il est légitime de décider qu'une relation de clé étrangère soit facultative, et le moyen de la représenter consiste à rendre la fin de la référence de la clé facultative, c'est-à-dire autoriser des valeurs NULL.
En termes de modélisation de données, ce que vous avez décrit est un arc (exclusif): "une table ... avec deux ou plusieurs clés étrangères où une et une seule d'entre elles peuvent être non nulles". En modélisation logique, les arcs sont parfaitement acceptables, mais il existe un fort courant d'opinion en faveur de leur mise en œuvre en tant que tableaux séparés. Dans votre scénario, il s'agirait d'une table générique Sale
et de deux tables de sous-types, VehicleSale
et PieceSale
.
Les avantages de la mise en œuvre de la table séparée sont les suivants:
Cependant, les avantages ne sont pas tous à sens unique. Bien qu'il soit assez facile de s'assurer qu'une Sale
s'applique soit à une VehicleSale
, soit à une PieceSale
mais pas aux deux, appliquer la règle qui dit que Sale
doit avoir un enregistrement enfant devient en réalité assez génial.
Ainsi, le conseil qui prévaut est qu'un arc exclusif se trompe et que c'est généralement un bon conseil. Mais ce n'est pas aussi clair que certains le prétendent.
Oui, vous pouvez le faire - rendre les FK eux-mêmes NULL, mais ajoutez un CHECK pour vous assurer que l'un d'entre eux contient une valeur non NULL.
Un FK peut être NULL, ce qui modélise une relation 1..0: N. En d'autres termes, une ligne "enfant" can (mais ce n'est pas obligatoire) a une ligne "parent".
Une clé étrangère NOT NULL modélise une relation 1: N. En d’autres termes, chaque enfant doit avoir un parent.
Quand un FK est composite1, et au moins un de ses champs est NULL, un mélange de valeurs NULL et non-NULL est traité de manière spéciale:
La plupart des SGBD ont la valeur par défaut MATCH SIMPLE (à l'exception notable de MS Access ) et la plupart ne prennent en charge que la valeur par défaut.
1 Ce que vous n'avez pas ici - en le mentionnant pour être complet.
Selon ce que vous entendez par "clés étrangères exclusives", vous pourriez penser à des véhicules et à des pièces en tant que deux sous-classes d'une classe supérieure plus grande, appelez-les articles vendables.
Si vous utilisez un modèle de conception appelé "héritage de table de classe", vous aurez trois tables, une pour la superclasse et une pour chaque table de sous-classe. Si, en outre, vous utilisez une conception appelée "clé primaire partagée", vous pouvez utiliser la même clé primaire pour les trois tables.
Cela permettrait à votre table Vente d'avoir une seule clé étrangère, Saleable_Item_Id, qui fait référence à la table Saleable_Item ainsi qu'à la table Vehicle ou à la pièce, selon le cas. Cela pourrait fonctionner mieux pour vous que la conception existante.
google "héritage table de classe" et "clé primaire partagée" pour plus de détails.
Oracle ne devrait pas se plaindre si vous avez une clé étrangère nulle.
Avez-vous rencontré des erreurs?