Sauf que dans 99.99% des cas, dans une base complexe, tes clé étrangères sont plus complexes qu'une simple relation bête entre deux tables, mais doivent s'assurer de la cohérence d'un certain nombre de paramètres.
Par exemple :
-> Une table "personne".
Tu peux modéliser un arbre généalogique en ajoutant deux champs "père" et "mère", pointant sur sur les id de "personne".
Seulement, une mère est forcément féminine, un père est forcément masculin. Deplus, la mère doit être vivante au moment de l'enfantement, le père doit être vivant au moins neuf mois avant l'enfantement, les parents doivent avoir au moins 14 ans de plus que l'enfant, etc. etc.
Bon, ben je te souhaite du courage pour gérer cette clé étrangère autrement qu'au niveau soft.
La gestion des clés dans une gestion de stocks par exemple est TRES LARGEMENT aussi compliquée. Il est donc ridicule de gérer les contraintes d'intégrité au nivea de la base pour les quelques tables minables qui restent, puisque la PREMIERE règle pour faire un développement propre et portable, c'est de regrouper toutes les fonctions de même niveau au même endroit : soit tout dans la base, soit rien dans la base. Mais pas p'tête ben que oui p'tête ben que non, avec le risque de valider plusieurs fois de suite les mêmes données, avec tout les risques que cela implique, par exemple qu'une vérification à un niveau invalide une vérification faite à un autre niveau, qu'on passe alors des mois à traquer pour corriger le bug.
Donc les clé étrangères, comme 80% d'un modèle de données, c'est pour faire joli dans le cahier des charges.
PS: c'est pas parceque c'est pour faire joli que ce n'est pas nécessaire. Il est vital d'avoir fait en amont une passe en MERISE pour débroussailler le terrain et comprendre comment le problème peut se résoudre. Mais très vite lors de la phase de conception, on abandonne tous les grands principes de MERISE qui ne sont pas adaptés à la vie réelle, au profit de traîtements moins jolis mais plus réalistes, et au final souvent plus propre malgré les apparences.