web-dev-qa-db-fra.com

Pourquoi devrais-je utiliser des clés étrangères dans la base de données?

Au cours de mes 10+ années d'expérience dans le domaine informatique, je n'ai jamais utilisé de clés étrangères dans aucun de mes projets et je n'en ai jamais ressenti le besoin. J'ai travaillé avec des bases de données professionnelles qui avaient des contraintes de clés étrangères.

Je suis maintenant dans une position où nous construisons une nouvelle application/base de données et je pense que devrais-je utiliser des clés étrangères ou non? Ce sera un produit professionnel. J'envisagerai également de mettre cela en œuvre dans mes projets existants si j'obtiens une réponse satisfaisante.

Cet article sur pourquoi utiliser des clés étrangères répond exactement à mes préoccupations. Le nœud principal est

  1. Il maintient l'intégrité référentielle (oui mais peut être maintenu sans cela aussi)
  2. Travail de détective plus facile (bien sûr)
  3. Meilleures performances (je ne suis pas sûr)

Ma question est, dois-je utiliser des clés étrangères ou puis-je vivre sans elles. Quels sont les avantages et les inconvénients d'un développeur qui a travaillé dans de tels scénarios.


Exemple: Maintenant, une partie importante de l'utilisation de clés étrangères est une complexité supplémentaire qui est ajoutée à la conception. Par exemple, une simple suppression peut ne pas fonctionner, ou elle peut supprimer d'autres enregistrements que vous ne connaissez pas. Prenons ce scénario.

J'ai une base de données avec user et user_comments les tables.

create table user(
user_id int not null identity,
user_name varchar(50),
...
)

create table user_comment(
comment_id int not nul identity,
user_id int,
CONSTRAINT FK_USER_USERID FOREIGN KEY (user_id)     
    REFERENCES user (user_id)
    ON DELETE CASCADE    
    ON UPDATE CASCADE 
)

Ici, si je supprime un utilisateur, tous ses commentaires seront automatiquement supprimés. Je sais que je peux changer ce comportement, mais ma question est, les clés étrangères valent-elles la peine d'être utilisées avec leur complexité supplémentaire? Quels sont les avantages et les inconvénients des utilisateurs de SE.stackexchange ? Suis-je potentiellement en train de regarder des histoires d'horreur? Quelqu'un peut-il commenter comment cela améliore les performances?

9
Noname
  1. Il maintient l'intégrité référentielle (oui mais peut être maintenu sans cela aussi)

Vous avez techniquement raison de dire que si vous êtes capable de maintenir vous-même l'intégrité référentielle, vous n'avez pas besoin de la contrainte pour exister. Mais selon cette même logique, vous n'avez pas besoin d'une assurance incendie tant que votre maison ne brûle pas, et vous n'avez pas besoin d'une assurance maladie tant que vous ne tombez pas malade.

Bien que techniquement correct, l'affirmation sous-jacente selon laquelle vous pouvez tout faire parfaitement est simplement un échec à reconnaître la possibilité que vous (ou tout autre développeur) commettiez une erreur.

Briser accidentellement l'intégrité référentielle sans les clés étrangères fonctionne sans aucun problème. Mais plus tard, lorsque vous souhaitez récupérer les données, cela vous explose.

  • Qui a défini ces données?
  • Quand l'ont-ils mis?
  • Pourquoi l'ont-ils réglé à cette valeur?

Il est très difficile de répondre à ces questions.

Briser accidentellement l'intégrité référentielle avec des clés étrangères vous saute au visage immédiatement .

  • Qui a défini ces données? Vous l'avez fait.
  • Quand ont-ils essayé de le régler? En ce moment.
  • Pourquoi l'ont-ils réglé à cette valeur? Puisque vous le faites en ce moment, vous êtes logiquement la meilleure source pour savoir ce que vous essayez de faire.

Résoudre le problème devient tellement plus facile lorsque vous êtes déjà à l'origine du problème.

  1. Travail de détective plus facile (bien sûr)

Je suppose que vous voulez dire la chose que je viens de décrire.

  1. Meilleures performances (je ne suis pas sûr)

Quelqu'un peut-il dire comment il améliore les performances?

Les clés étrangères n'améliorent pas les performances, du moins pas directement. Le gain de performances est obtenu par l'utilisation de index. Il se trouve que les PK et FK sont automatiquement indexés car ils sont très fréquemment utilisés pour la recherche, ce qui en fait des cibles privilégiées pour l'optimisation de la recherche.

Ici, si je supprime un utilisateur, tous ses commentaires seront automatiquement supprimés.

Ce n'est pas inhérent à une clé étrangère. Cela est inhérent à la définition de ON DELETE CASCADE sur la clé étrangère. Les suppressions en cascade sont une fonctionnalité intéressante, mais elles ne sont pas le cas d'utilisation principal des clés étrangères. Le cas d'utilisation principal est de maintenir l'intégrité référentielle.

Ma question est de savoir si je dois utiliser des clés étrangères ou puis-je vivre sans. Quels sont les avantages et les inconvénients d'un développeur qui a travaillé dans de tels scénarios.

ma question est, est-ce que les clés étrangères valent la peine d'être utilisées avec leur complexité supplémentaire

Je ne vois pas la complexité dont vous parlez.

Si vous prétendez déjà être capable de gérer l'intégrité référentielle, cela signifie que je devrais être capable de mettre sournoisement un FK sur votre colonne sans FK, et vous ne pourrez pas remarquer que j'ai mis un FK sur votre colonne. Il n'y a aucune complexité d'avoir le FK.

La configuration du FK est triviale. Oui, cela nécessite une commande SQL explicite, mais la commande est très copiable/collable:

CONSTRAINT unique_name FOREIGN KEY fk_column_name REFERENCES pk_table (pk_column_name)

Alors que le développeur paresseux en moi se demande si nommer une contrainte est vraiment nécessaire, les autres informations que vous devez ajouter sont logiquement toujours nécessaires pour établir une relation entre deux colonnes. À part le nom, c'est à peu près aussi simple que possible.

Le gain de performances d'avoir un index sur la colonne est inhérent à avoir un FK sur la colonne. La définition d'un index sans FK est à peu près aussi complexe que la définition d'un FK:

CREATE INDEX unique_name ON fk_table_name (fk_column_name)

Encore une fois, je ne vois pas la complexité supplémentaire de l'utilisation réelle d'une clé étrangère.

27
Flater

Si vous supprimez un utilisateur, pourquoi voudriez-vous éventuellement vouloir conserver ses commentaires maintenant orphelins?

L'avantage central d'un magasin de données relationnelles est de pouvoir garantir que de telles anomalies ne se produisent jamais. Si vous aimez et voulez de telles garanties, alors c'est une bonne idée de les implémenter au niveau le plus bas possible, c'est-à-dire de les intégrer dans le moteur de base de données, car c'est plus rapide et plus sûr que de le faire vous-même.

Si vous ne les voulez pas, vous êtes mieux avec un magasin de données non relationnel. Mais utiliser un modèle de moteur puis refuser de profiter de l'un de ses principaux avantages semble étrangement inutile.

3
Kilian Foth