web-dev-qa-db-fra.com

L'utilisation de plusieurs clés étrangères sur la même colonne dans SQL Server

SQL Server me permet de créer plusieurs clés étrangères sur une colonne, et chaque fois en utilisant un nom différent, je peux créer une autre clé faisant référence au même objet. Fondamentalement, toutes les clés définissent la même relation. Je veux savoir à quoi sert d'avoir plusieurs clés étrangères définies sur la même colonne et faisant référence à la même colonne dans une autre table. Quel est l'avantage de cela que SQL Server nous permet de faire une chose comme ça?

enter image description here

10
igelr

Il n'y a aucun avantage à avoir des contraintes redondantes qui ne diffèrent que par leur nom. De même, il n'y a aucun avantage à avoir des index redondants qui ne diffèrent que par leur nom. Les deux ajoutent des frais généraux sans valeur.

Le moteur de base de données SQL Server ne vous en empêche pas. De bonnes conventions de dénomination des contraintes (par exemple FK_ReferencingTable_ReferencedTable) peuvent aider à protéger une personne contre de telles erreurs.

12
Dan Guzman

SQL Server vous permet de faire beaucoup de choses stupides.

Vous pouvez même créer une clé étrangère sur une colonne se référençant elle-même - malgré le fait que cela ne peut jamais être violé car chaque ligne rencontrera la contrainte sur elle-même.

Un cas Edge où la possibilité de créer deux clés étrangères sur la même relation serait potentiellement utile est que l'index utilisé pour valider les clés étrangères est déterminé au moment de la création. Si un meilleur index (c'est-à-dire plus étroit) apparaît plus tard, cela permettrait de créer une nouvelle contrainte de clé étrangère liée au meilleur index, puis la contrainte d'origine supprimée sans aucun écart sans contrainte active.

(Comme dans l'exemple ci-dessous)

CREATE TABLE T1(
    T1_Id INT PRIMARY KEY CLUSTERED  NOT NULL,
    Filler CHAR(4000) NULL,
) 

INSERT INTO T1 VALUES (1, '');

CREATE TABLE T2(
    T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id), 
    Filler CHAR(4000) NULL,
)


ALTER TABLE T1 ADD CONSTRAINT
    UQ_T1 UNIQUE NONCLUSTERED(T1_Id) 


/*Execution Plan uses clustered index*/ 
INSERT INTO T2 VALUES (1,1) 

ALTER TABLE T2  WITH CHECK ADD  CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)    

ALTER TABLE T2 DROP CONSTRAINT FK

/*Now Execution Plan now uses non clustered index*/    
INSERT INTO T2 VALUES (1,1)    

DROP TABLE  T2, T1;

En aparté pour la période intérimaire alors que les deux contraintes existent, tous les inserts finissent par être validés par rapport aux deux indices.

17
Martin Smith

Il est inutile d'avoir des contraintes de clé étrangère identiques., C'est-à-dire sur les mêmes colonnes et référençant les mêmes tables et colonnes.

C'est comme avoir le même contrôle 2 fois ou plus.

13
ypercubeᵀᴹ

Même raison pour laquelle vous pouvez créer 50 index sur la même colonne, ajouter un deuxième fichier journal, définir la mémoire maximale du serveur à 20 Mo ... la plupart des gens ne feront pas ces choses, mais il peut y avoir des raisons légitimes de les faire occasionnellement, donc il n'y a pas avantage à créer des frais généraux dans le moteur pour ajouter des vérifications contre des choses qui sont simplement mal avisées.

6
Aaron Bertrand

Cela ressemble à une chose bleu-vert.

Lorsque vous commencez à passer du bleu au vert, vous devez créer temporairement des copies supplémentaires de choses.

Ce que nous voulons faire, c'est créer temporairement une clé étrangère supplémentaire CHECK WITH NOCHECK et ON UPDATE CASCADE ON DELETE SET NULL; cela signifie que c'est une clé étrangère qui fonctionne, mais les lignes existantes ne sont pas vérifiées lors de la création de la clé.

Plus tard, après avoir nettoyé toutes les lignes qui devraient correspondre, nous créerions la nouvelle clé étrangère sans aucune option de commande (la valeur par défaut est CHECK WITH CHECK, ce que vous souhaitez généralement) et supprimez la clé étrangère temporaire.

Notez que si vous venez de supprimer et de recréer la clé étrangère, certaines lignes de mémoire peuvent glisser par vous.

2
Joshua