Pourquoi une table utiliserait-elle sa clé primaire comme clé étrangère pour elle-même

21

En parcourant une base de données, je suis tombé sur une table qui utilisait sa clé primaire comme clé étrangère pour elle-même.

J'ai vu qu'une table peut avoir une clé étrangère pour construire une structure de hiérarchie, mais elle utiliserait une autre colonne pour référencer la clé primaire.

Étant donné que la clé primaire est unique, dans cette situation, la ligne ne pourrait-elle pas seulement pointer vers elle-même? Cela semble être un lien tautologique, car si j'ai déjà la rangée, alors j'ai déjà la rangée.

Y a-t-il une raison pour laquelle cela serait fait?

Table jointe à elle-même

Je suis certain que la contrainte est écrite de cette façon (pas seulement en regardant le diagramme) car le même tableau et la même colonne sont utilisés pour les deux moitiés de la définition.

Aaroninus
la source
6
Probablement grâce à l'utilisation du concepteur par les mains, c'est ma théorie
Martin Smith

Réponses:

28

Comme tu as dis. Une FOREIGN KEYcontrainte référençant la même table concerne généralement une structure hiérarchique et utilise une autre colonne pour référencer la clé primaire. Un bon exemple est un tableau des employés:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Donc, dans ce cas, il y a une clé étrangère de la table sur elle-même. Tous les gestionnaires sont également employés pour l' ManagerIdest en fait le EmployeeIddu gestionnaire.

Maintenant, d'autre part, si vous voulez dire que quelqu'un a utilisé la EmployeeIdclé étrangère pour revenir à la table des employés, c'était probablement une erreur . J'ai fait un test et c'est possible mais ça n'aurait pas vraiment d'utilité.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);
Kenneth Fisher
la source
1
Placer une contrainte sur le ManagerId concernant le EmployeeId dans ce cas pourrait être bénéfique si le gestionnaire devait être «séparé». Elle ne permettrait pas la suppression de la ligne si elle était définie de cette façon. Je ne dis pas que je le ferais de cette façon, mais cela pourrait avoir un certain avantage si votre demande reposait sur des employés ayant des gestionnaires.
zgr024
6

Je viens de trouver une telle clé étrangère dans ma propre base de données et ce doit être moi-même qui l'a créée. Je pense que c'est arrivé par accident. Si je clique sur "Nouvelle clé étrangère" dans le menu contextuel d'une table avec une clé primaire (dans Management Studio, SQL 2014 Express), cela crée déjà automatiquement une telle clé étrangère se référant à elle-même. Voir ci-dessous:

entrez la description de l'image ici

Si je ne me rends pas compte que je devrais le modifier au lieu d'en ajouter un nouveau, il y restera. Ou, si je clique simplement sur le bouton [Fermer] ce qui signifie que ce serait comme un [Annuler], la clé étrangère sera toujours créée après avoir enregistré la définition de la table.

Donc, pour moi, une telle clé étrangère n'a aucun sens et peut être supprimée.

Stefan Müller
la source
Il est possible que vous vouliez créer un FK et au cours du processus, vous réalisez que l'autre table n'a pas encore défini son PK, alors vous annulez, allez à l'autre table et, pour une raison quelconque, vous oubliez de poursuivre le processus FK. Voilà votre FK récursif.
Andrew
4

Peut-être que le concepteur voulait désactiver l'utilisation de TRUNCATE TABLE?

TRUNCATE TABLEne peut pas être utilisé sur une table avec une contrainte de clé étrangère vers une autre table bien qu'il puisse être utilisé s'il existe des clés étrangères auto-référentielles . Dans la documentation de TRUNCATE TABLE (Transact-SQL) :

Extrait BOL

Une DELETEinstruction sans WHEREclause a un effet similaire à a TRUNCATE TABLE(suppression de toutes les lignes du tableau) mais l' DELETEinstruction déclenche des déclencheurs de suppression, ce qui peut être une raison pour autoriser DELETEmais pas TRUNCATE TABLE.

Je le ferais en utilisant des autorisations ( DELETEnécessite une autorisation de suppression, une autorisation de TRUNCATE TABLEmodification de table), mais peut-être qu'il y a une raison pour laquelle le concepteur n'a pas pu le faire?

Remarque: Même si ce que le concepteur a fait ne désactive pas réellement l'utilisation de TRUNCATE TABLE, je spécule toujours que c'était leur intention.

Marcheur de Greenstone
la source