web-dev-qa-db-fra.com

Une clé étrangère peut-elle être NULL et/ou dupliquée?

S'il vous plaît clarifier deux choses pour moi:

  1. Une clé étrangère peut-elle être NULL?
  2. Une clé étrangère peut-elle être dupliquée?

Aussi juste que je sache, NULL ne devrait pas être utilisé dans les clés étrangères, mais dans certaines de mes applications, je peux entrer NULL dans Oracle et SQL Server, et je ne sais pas pourquoi.

225
jams

Réponse courte: Oui, cela peut être NULL ou dupliquer.

Je veux expliquer pourquoi une clé étrangère peut avoir besoin d'être nulle ou peut être unique ou pas unique. Tout d’abord, rappelez-vous qu’une clé étrangère exige simplement que la valeur de ce champ existe d’abord dans une table différente (la table parent). C'est tout ce qu'un FK est par définition. Null par définition n'est pas une valeur. Null signifie que nous ne savons pas encore quelle est la valeur.

Laissez-moi vous donner un exemple concret. Supposons que vous disposiez d'une base de données contenant les propositions de vente. Supposons en outre que chaque proposition ne comporte qu'un seul commercial et un seul client. Ainsi, votre table de propositions comporterait deux clés étrangères, l’une avec l’ID client et l’autre avec l’ID commercial. Toutefois, au moment de la création de l'enregistrement, un représentant commercial n'est pas toujours affecté (car personne n'est libre de travailler dessus pour l'instant). L'ID client est donc renseigné, mais cet ID peut être null. En d'autres termes, vous avez généralement besoin de la possibilité d'avoir un FK nul lorsque vous ne connaissez peut-être pas sa valeur au moment de la saisie des données, mais que vous connaissez d'autres valeurs du tableau qui doivent être entrées. Pour autoriser les valeurs NULL dans un FK, il suffit généralement de les autoriser sur le champ contenant le FK. La valeur null est distincte de l'idée qu'il s'agisse d'un FK. 

Qu'il soit unique ou non, cela dépend du fait que la table a une relation un-un ou un-plusieurs avec la table parente. Maintenant, si vous avez une relation un-un, il est possible que vous disposiez de toutes les données dans une seule table, mais si la table est trop large ou si les données portent sur un sujet différent (l'employé - exemple d'assurance @tbone donné par exemple), alors vous voulez des tables séparées avec un FK. Vous voudriez alors faire de ce FK soit aussi le PK (qui garantit l'unicité), soit lui imposer une contrainte unique. 

La plupart des FKs sont pour une relation un à plusieurs et c'est ce que vous obtenez d'un FK sans ajouter de contrainte supplémentaire sur le champ. Vous avez donc une table de commandes et la table de détails de commandes par exemple. Si le client commande dix articles à la fois, il dispose d'un enregistrement de commande et de dix enregistrements de commande détaillés contenant le même ID de commande que le FK. 

401
HLGEM

1 - Oui, depuis au moins SQL Server 2000.

2 - Oui, tant que ce n'est pas une contrainte UNIQUE ou lié à un index unique.

46
JNK

De la bouche du cheval:

Les clés étrangères autorisent des valeurs de clé qui sont toutes NULL, même s'il n'y a pas de correspondance des clés PRIMARY ou UNIQUE 

Pas de contrainte sur la clé étrangère

Lorsqu'aucune autre contrainte n'est définie sur la clé étrangère, n'importe quel nombre nombre de lignes dans la table enfant peut faire référence à la même valeur de clé parent . Ce modèle autorise les valeurs NULL dans la clé étrangère. ...

NOT NULL Contrainte sur la clé étrangère

Lorsque les valeurs NULL ne sont pas autorisées dans une clé étrangère, chaque ligne de la table enfant doit explicitement référencer un valeur dans la clé parente car les valeurs NULL ne sont pas autorisées dans le fichier étranger. clé.

N'importe quel nombre de lignes dans la table enfant peut faire référence au même parent valeur clé, ce modèle établit donc une relation un-à-plusieurs entre le parent et les clés étrangères. Cependant, chaque ligne de l'enfant table doit avoir une référence à une valeur de clé parent; l'absence d'un valeur (null) dans la clé étrangère n'est pas autorisée. Le même exemple dans la section précédente peut être utilisée pour illustrer une telle relation . Cependant, dans ce cas, les employés doivent avoir une référence à un .__ spécifique. département.

Contrainte UNIQUE sur la clé étrangère

Lorsqu'une contrainte UNIQUE est défini sur la clé étrangère, une seule ligne de la table enfant peut référencer une valeur de clé parent donnée. Ce modèle autorise les valeurs NULL dans le fichier clé étrangère.

Ce modèle établit une relation un à un entre le parent et des clés étrangères qui permettent des valeurs indéterminées (NULL) dans le fichier clé étrangère. Par exemple, supposons que la table employee comporte une colonne nommé MEMBERNO, faisant référence à un numéro de membre d’employé dans le plan d'assurance entreprise. En outre, une table nommée INSURANCE a un primaire la clé nommée MEMBERNO, et les autres colonnes de la table conservent respectives informations relatives à une police d’assurance des employés. Le MEMBERNO dans la table employee doit être à la fois une clé étrangère et une clé unique:

  • Pour appliquer des règles d'intégrité référentielle entre EMP_TAB et Tables d'ASSURANCES (contrainte FOREIGN KEY)

  • Pour garantir que chaque employé a un numéro de membre unique (la contrainte de clé UNIQUE)

Contraintes UNIQUE et NOT NULL sur la clé étrangère

Lorsque les deux UNIQUE et les contraintes NOT NULL sont définies sur la clé étrangère, une seule ligne dans la table enfant peut référencer une valeur de clé parent donnée, et parce que Les valeurs NULL ne sont pas autorisées dans la clé étrangère, chaque ligne de l'enfant table doit explicitement référencer une valeur dans la clé parente.

Regarde ça:

Lien Oracle 11g

37
tbone

Oui, la clé étrangère peut être nulle comme indiqué ci-dessus par les programmeurs expérimentés ... J'ajouterais un autre scénario dans lequel la clé étrangère doit être nulle ...... Supposons que nous ayons des tableaux de commentaires, d'images et de vidéos dans une application permettant les commentaires. sur des photos et des vidéos. Dans le tableau des commentaires, nous pouvons avoir deux images étrangères clés, PicturesId et VideosId, ainsi que la clé principale CommentId. Ainsi, lorsque vous commentez une vidéo, seul VideosId sera requis et pictureId sera null ... et si vous commentez une image, seul PictureId sera requis et VideosId sera nul ... 

15
Touseef Ahmed Awan

cela dépend du rôle que ce foreign key joue dans votre relation.

  1. si ce foreign key est également un key attribute dans votre relation, il ne peut pas être NULL
  2. si ce foreign key est un attribut normal dans votre relation, il peut alors être NULL.
5
shinxg

Voici un exemple utilisant la syntaxe Oracle:
Commençons par créer une table COUNTRY

CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;

Créer la table PROVINCE

CREATE TABLE TBL_PROVINCE(
PROVINCE_ID VARCHAR2 (50) NOT NULL ,
COUNTRY_ID  VARCHAR2 (50)
);
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;

Cela fonctionne parfaitement dans Oracle. Notez que la clé étrangère COUNTRY_ID dans la deuxième table n'a pas "NOT NULL".

Maintenant, pour insérer une ligne dans la table PROVINCE, il suffit de spécifier uniquement le PROVINCE_ID. Toutefois, si vous choisissez également de spécifier un COUNTRY_ID, celui-ci doit déjà exister dans la table COUNTRY.

3
Mouhcine

Par défaut, il n'y a pas de contrainte sur la clé étrangère. Cette clé peut être nulle et dupliquer.

lors de la création/modification de la table, si vous ajoutez une contrainte d’unicité ou une valeur non nulle, cela n’autorisera pas les valeurs null/dupliqué.

1
nitin lalwani

En termes simples, les relations "non identifiantes" entre entités font partie de ER-Model et sont disponibles dans Microsoft Visio lors de la conception de ER-Diagram. Cela est nécessaire pour appliquer la cardinalité entre entités de type "zéro ou plus que zéro" ou "zéro ou un". Notez ce "zéro" dans la cardinalité au lieu de "un" dans "un à plusieurs".

Maintenant, un exemple de relation non identifiante où la cardinalité peut être "zéro" (non identifiante) est le cas où un enregistrement/objet dans une entité-A "peut" ou "ne peut pas" avoir une valeur en tant que référence à l'enregistrement/s dans une autre entité-B. 

Comme il est possible qu'un enregistrement de l'entité-A s'identifie aux enregistrements de l'autre entité-B, il devrait donc y avoir une colonne dans Entité-B pour avoir la valeur d'identité de l'enregistrement de l'entité-B. Cette colonne peut être "Null" si aucun enregistrement dans Entité-A n'identifie le ou les enregistrements (ou objet) dans Entité-B. 

Dans le paradigme orienté objet (monde réel), il existe des situations où un objet de classe B ne dépend pas nécessairement (fortement couplé) d'un objet de classe A pour son existence, ce qui signifie que la classe B est faiblement couplée à la classe Une classe telle que la classe A peut "contenir" (confinement) un objet de classe A, par opposition au concept d'objet de classe B, doit avoir (composition) un objet de classe A, pour son objet de classe B) création.

Du point de vue de la requête SQL, vous pouvez interroger tous les enregistrements de l'entité-B qui ne sont "pas nuls" pour la clé étrangère réservée à l'entité-B. Cela amènera tous les enregistrements ayant une certaine valeur correspondante pour les lignes de l'entité-A, sinon tous les enregistrements avec une valeur nulle seront les enregistrements qui n'ont aucun enregistrement dans l'entité-A dans l'entité-B.

0
Fakhar

L'idée d'une clé étrangère est basée sur le concept de référencement d'une valeur qui existe déjà dans la table principale. C'est pourquoi on l'appelle une clé étrangère dans l'autre table. Ce concept s'appelle intégrité référentielle. Si une clé étrangère est déclarée comme un champ nul, cela violera la logique même de l'intégrité référentielle. À quoi fera-t-il référence? Il ne peut que faire référence à quelque chose qui est présent dans la table principale. Par conséquent, j'estime qu'il serait faux de déclarer un champ de clé étrangère comme nul. 

0
SQLDev