Pourquoi les clés étrangères sont-elles plus utilisées en théorie qu'en pratique?

quand vous étudiez la théorie relationnelle, les clés étrangères sont, bien sûr, obligatoires. Mais dans la pratique, à chaque endroit où j'ai travaillé, les produits de table et les jointures sont toujours faits en spécifiant explicitement les clés dans la requête, au lieu de compter sur des clés étrangères dans le SGBD.

de cette façon, vous pourriez bien sûr rejoindre deux tables par des champs qui ne sont pas censés être des clés étrangères, ayant des résultats inattendus.

Pourquoi pensez-vous que c'est? Ne devrait pas DBMSs appliquer que des jointures et des produits soient faits seulement par des clés étrangères?

EDIT: Merci pour toutes les réponses. Il est clair pour moi maintenant que la raison principale de FKs est l'intégrité de référence. Mais si vous concevez une DB, toutes les relations dans le modèle (c'est-à-dire les flèches dans L'ERD) deviennent des clés étrangères, au moins en théorie, que vous les définissiez ou non comme telles dans votre SGBD, elles sont sémantiquement FKs. Je ne peux pas imaginer le besoin de rejoindre les tables par des champs qui ne sont pas des FKs. est-ce que quelqu'un peut donner un exemple qui fait sens?

PS:je suis conscient du fait que les relations N: M deviennent des tables séparées et pas des clés étrangères, je l'ai simplement omise pour des raisons de simplicité.

46
demandé sur Petruza 2009-12-09 21:50:50

17 réponses

la raison pour laquelle des contraintes de clé étrangère existent est de garantir que les lignes référencées existent.

"La clé étrangère identifie une colonne ou un ensemble de colonnes dans une table qui fait référence à une colonne ou un ensemble de colonnes d'une autre table. Les valeurs dans une rangée des colonnes de référence doivent apparaître dans une seule rangée du tableau de référence.

ainsi, une ligne dans le tableau de référence ne peut pas contenir des valeurs qui n'existent pas dans le tableau référencé (sauf potentiellement nul). De cette façon, des références peuvent être faites pour relier l'information ensemble et c'est un élément essentiel de la normalisation des bases de données."( Wikipedia )


RE: Votre question: "je ne peux pas imaginer la nécessité de joindre des tables de champs qui ne sont pas FKs":

lors de la définition d'une contrainte de clé étrangère, la ou les colonnes du tableau de référence doivent être les principales la clé de la table référencée, ou au moins une clé candidate.

lorsqu'on fait des jointures, il n'est pas nécessaire de se joindre avec des clés primaires ou des clés candidates.

voici un exemple qui pourrait avoir un sens:

CREATE TABLE clients (
    client_id       uniqueidentifier  NOT NULL,
    client_name     nvarchar(250)     NOT NULL,
    client_country  char(2)           NOT NULL
);

CREATE TABLE suppliers (
    supplier_id       uniqueidentifier  NOT NULL,
    supplier_name     nvarchar(250)     NOT NULL,
    supplier_country  char(2)           NOT NULL
);

puis interrogez comme suit:

SELECT 
    client_name, supplier_name, client_country 
FROM 
    clients 
INNER JOIN
    suppliers ON (clients.client_country = suppliers.supplier_country)
ORDER BY
    client_country;

un autre cas où ces jointures ont du sens est celui des bases de données qui offrent des fonctionnalités géospatiales, comme SQL Server 2008 ou Postgres avec PostGIS. Vous sera capable de faire des requêtes comme celles-ci:

SELECT
    state, electorate 
FROM 
    electorates 
INNER JOIN 
    postcodes on (postcodes.Location.STIntersects(electorates.Location) = 1);

Source: ConceptDev - SQL Server 2008 Géographie: STIntersects, STArea

vous pouvez voir un autre exemple géospatial semblable dans la réponse acceptée au problème de requête POST " Sql 2008 - quel LatLong existe dans un polygone de géographie? ":

SELECT 
    G.Name, COUNT(CL.Id)
FROM
    GeoShapes G
INNER JOIN 
    CrimeLocations CL ON G.ShapeFile.STIntersects(CL.LatLong) = 1
GROUP BY 
    G.Name;

ce sont tous des jointures SQL valides qui n'ont rien à voir avec des touches et candidat clés, et peut encore être utile dans la pratique.

38
répondu Daniel Vassallo 2017-05-23 12:32:14

les clés étrangères ont moins à voir avec les jointures qu'avec le maintien de l'intégrité de la base de données. La preuve de cela est que vous pouvez joindre les tables de n'importe quelle façon que vous voulez, même dans des façons qui ne sont pas nécessairement sensées.

34
répondu Otávio Décio 2009-12-09 19:05:27

Je ne peux pas imaginer la nécessité de joindre les tables par des champs qui ne sont pas FKs. Quelqu'un peut-il donner un exemple qui fait sens?

FOREIGN KEY s ne peut être utilisé pour renforcer l'intégrité référentielle que si la relation entre les entités du modèle ER se reflète avec un équijoin entre deux relations dans le modèle relationnel.

Ce n'est pas toujours vrai.

voici un exemple tiré de l'article de mon blog que j'ai écrit il y a quelque temps:

Ce modèle décrit des marchandises et des gammes de prix:

et voici la mise en œuvre relationnelle du modèle:

CREATE TABLE Goods (ID, Name, Price)
CREATE TABLE PriceRange (Price, Bonus)

Comme vous pouvez le voir, le PriceRange le tableau n'a qu'un attribut lié au prix, Price , mais le modèle a deux attributs: StartPrice et EndPrice .

c'est parce que le modèle relationnel permet de transformer les ensembles et l'entité PriceRange peut être facilement reconstruit en utilisant des opérations SQL .

Goods
ID  Name               Price
1   Wormy apple        0.09
2   Bangkok durian     9.99
3   Densuke watermelon 999.99
4   White truffle      99999.99

PriceRange
Price   Bonus
0.01       1%
1.00       3%
100.00    10%
10000.00  30%

nous stockons seulement la limite inférieure de chaque gamme. La limite supérieure peut facilement être déduite.

Voici la requête pour trouver le bonus pour chaque bien:

SELECT  *
FROM    Goods
JOIN    PriceRange
ON      PriceRange.Price =
        (
        SELECT  MAX(Price)
        FROM    PriceRange
        WHERE   PriceRange.Price <= Goods.Price
        )

nous voyons que ce modèle relationnel implémente assez bien le Modèle ER, mais aucune clé étrangère ne peut être déclarée entre ces relations, puisque l'opération utilisée pour les lier n'est pas un equijoin.

10
répondu Quassnoi 2017-02-08 14:18:08

Non, l'application n'est pas nécessaire; elle interdirait certaines fonctionnalités utiles, telles que la possibilité de surcharger les colonnes. Bien que ce type d'utilisation ne soit pas idéal, elle est utile dans certaines situations réelles.

l'utilisation appropriée pour les contraintes de clé étrangère est tout comme cela; une contrainte sur les valeurs ajoutées à une colonne donnée qui assure que leurs lignes référencées existent.

Il convient de noter qu'un manque important de clé étrangère contraintes sur un schéma donné est une mauvaise "odeur", et peut indiquer certains de graves problèmes de conception.

8
répondu Paul Sonier 2009-12-09 18:57:54

vous pouvez Vous joindre à n'importe quelle expression. Que vous définissiez des clés étrangères dans votre base de données ou non est sans importance. Les touches étrangères restreignent L'insertion / la mise à jour / la suppression, pas la sélection.

alors pourquoi beaucoup de projets sautent-ils la définition des clés étrangères? Il y a plusieurs raisons:

  • le modèle de données est mal conçu et nécessite des références brisées (exemples: associations polymorphiques, EAV).

  • Les codeurs ont pu entendre que "les clés étrangères sont lentes" alors ils les laissent tomber. En fait, le travail supplémentaire que vous avez à faire pour assurer la cohérence des données lorsque vous ne pouvez pas compter sur des clés étrangères rend votre application beaucoup moins efficace. L'optimisation prématurée sans mesurer réellement le bénéfice est un problème commun.

  • les contraintes gênent certaines tâches de nettoyage des données. Parfois, vous devez briser les références Temporairement que vous refactor données. De nombreux SGBDR permettent contraintes d'être désactivé, mais parfois les programmeurs décident qu'il est plus facile de laisser eux désactivé. S'il y a un besoin fréquent de désactiver les contraintes, cela indique probablement une conception de base de données gravement défectueuse.

6
répondu Bill Karwin 2009-12-09 19:08:48

clés étrangères utilisées de la manière que vous décrivez n'est pas la façon dont elles sont destinées à être utilisées. Ils sont destinés à s'assurer que si un document dépend logiquement d'un document correspondant exister ailleurs, que ce document correspondant est effectivement là.

je crois que si les développeurs/AD ont le temps de (A) développer de bons noms pour leurs tables et leurs champs, OU (B) définir des contraintes étendues de clé étrangère, l'option A est le choix facile. J'ai travaillé dans les deux situations. Où de nombreuses contraintes ont été invoqués pour maintenir l'ordre et empêcher les gens de vissage des choses peut vraiment devenir un gâchis.

il faut beaucoup d'efforts pour garder toutes vos contraintes de clé étrangère à jour pendant le développement, le temps que vous pourriez passer sur d'autres tâches de grande valeur que vous avez à peine le temps pour. En revanche, dans les situations où vous avez de bonnes conventions de nommage, les clés étrangères sont instantanément claires. Les développeurs n'ont pas pour chercher des clés étrangères, ou essayez une requête pour voir si elle fonctionne; il suffit de voir les relations.

je pense que les contraintes des clés étrangères deviennent rapidement utiles au fur et à mesure que le nombre d'équipes différentes augmente à l'aide d'une base de données. Il devient difficile d'appliquer un système de nommage cohérent; la connaissance de la base de données devient fragmentée; il est facile pour les actions de la base de données d'avoir des conséquences involontaires pour une autre équipe.

3
répondu Patrick Karcher 2009-12-09 19:15:25

Parce que, dans la pratique, la théorie n'est pas assez ;)

Sérieusement, dans mon expérience est principalement parce que la théorie n'est pas assez souple pour envisager toutes les possibilités que vous avez à gérer dans le monde réel. Seulement avec un cas extrêmement bizarre que vous devez stocker dans votre DB (ou quelque chose de plus commun, comme les colonnes de surcharge), vous devez sortir le FK et l'implémenter dans le DAL.

Peut-être vous pouvez développer une solution qui peut être archivée d'une manière totalement normalisée (par exemple), mais dans de nombreux cas, le travail nécessaire et/ou les résultats finaux ne valent pas assez.

mes deux cents.

3
répondu j.a.estevan 2009-12-29 00:46:51
Les SGBD

sont construits pour permettre le plus grand nombre de solutions tout en travaillant selon leurs règles de base.

restreindre les jointures à des clés étrangères définies limiterait énormément la fonctionnalité, d'autant plus que la plupart des développements ne se produisent pas avec un DBA dédié ou un examen des procédures SQL/stockées.

ayant dit que, selon votre couche D'accès aux données, vous pourriez être requis de configurer des clés étrangères, pour utiliser la fonctionnalité. Exemple Linq to SQL.

2
répondu Bravax 2009-12-09 19:01:17

clés étrangères ne sont pas utilisés aussi souvent que la théorie relationnelle suggère parce que DB/personnes de type relationnel n'écrivent pas beaucoup du code ou même concevoir les tables. Les programmeurs écrivent les tables de code/conception ou ont beaucoup d'influence sur la façon dont les tables sont conçues.

2
répondu ElGringoGrande 2009-12-09 19:13:37

sur quel type d'applications de base de données travaillez-vous? La théorie que vous voyez souvent concerne l'utilisation de la base de données brute, dans ce cas, les contraintes peuvent être très utiles. Dans la pratique, les bases de données sont souvent utilisées comme la fin des applications plus importantes. Dans de nombreux cas, ces applications doivent valider les transactions elles-mêmes, et il serait inutile de le répéter dans la base de données.

envisager une application de vente, par exemple. Quand quelqu'un est saisie d'une pour obtenir l'adresse ou les informations sur la carte de crédit. Quand il ne trouve pas de client, il sera programmé pour faire quelque chose de raisonnable. S'il attendait jusqu'à ce qu'il a essayé d'insérer une rangée dans la table de commande pour découvrir qu'il n'y avait pas de client, il obtiendrait des commentaires plus lents et moins pratiques.

quelque chose doit maintenir l'intégrité de la base de données, mais le faire à l'intérieur du SGBD lui-même n'est pas toujours la meilleure façon.

2
répondu David Thornley 2009-12-09 19:16:46

je programmais depuis quelques décennies, bien avant que les bases de données relationnelles ne deviennent la norme. Quand J'ai commencé à travailler avec MySQL quand je me suis enseigné Le PHP, j'ai vu L'option de la clé étrangère et la toute première pensée était "Wow! C'est retardée."La raison n'être qu'un imbécile croit que le laboratoire dicte la réalité. Il était évident immédiatement qu'à moins de coder une application qui ne serait jamais, jamais , être changée, vous emballez votre application dans une coulée d'acier où la seule option est de construire plus de tables ou de trouver des solutions créatives.

cette première évaluation était née dans chaque application de production réelle que j'ai rencontrée. Non seulement la contrainte ralentit considérablement toutes les modifications, mais elle rend presque impossible la croissance de l'application, ce qui est requis pour une entreprise.

la seule raison que j'ai jamais trouvé pour les contraintes sur la table est paresseux codeurs. Pas prêt à écrire du code propre pour vérifier l'intégrité des données.

Michael

2
répondu Michael 2010-10-11 21:33:20

les clés étrangères sont extrêmement importantes, en particulier dans les bases de données où des requêtes manuelles sont exécutées ou pour lesquelles un logiciel est activement développé. Chaque requête non testée qui est exécutée sur la base de données a la possibilité de contenir une erreur. Des contraintes telles que les clés étrangères servent à mettre en évidence ces erreurs avant que l'incohérence ne soit introduite dans les données.

ces contraintes sont appliquées par le concepteur du schéma, et elles assurent que les données reste dans le modèle qu'il a envisagé. Si les contraintes ne sont pas là, alors tôt ou tard une requête introduira une certaine incohérence. L'incohérence conduira à des résultats imprévisibles à partir des requêtes, et est très difficile à inverser.

1
répondu Paul 2009-12-09 20:34:56

bonne question. Je me suis toujours demandé pourquoi SQL n'a pas une syntaxe comme

SELECT tbl1.col1, tbl2.col2
  FROM tbl1
  JOIN tbl2 USING(FK_tbl1_tbl2)

où FK_tbl1_tbl2 est une contrainte étrangère entre les tables. Ce serait incroyablement beaucoup plus utile que la jointure naturelle ou L'utilisation D'Oracle(col1, col2).

0
répondu erikkallen 2009-12-10 12:59:49

la raison principale est qu'il n'y a aucun moyen de les configurer sans une requête dans la plupart des outils GUI MySQL (Navicat, MySQL, etc.)

semble stupide mais je suis coupable de cela aussi bien puisque je n'ai pas la syntaxe mémorisée: /

0
répondu Andrew G. Johnson 2009-12-10 17:28:36

une partie de cela pour moi est que (et oui, c'est une excuse bidon) L'UI dans le studio de gestion de Serveur SQL DE MS pour ajouter des clés étrangères est terrible .

une clé étrangère est une contrainte que" toute valeur dans la colonne x de la table a doit apparaître dans la colonne y de la table b", mais L'UI pour la spécifier dans le SSMS n'indique pas clairement quelle table vous jouez avec, qui est la table mère, qui est la table enfant, et ainsi de suite.

chaque fois que j'ai dû créer une clé étrangère, c'était par tâtonnements jusqu'à ce qu'elle semble fonctionner.

0
répondu Aric TenEyck 2009-12-10 17:30:26

Je ne suis pas au courant d'un dialecte SQL qui rejoint automatiquement toutes les tables de clés étrangères implicitement. J'ai vu la génération de code et les outils de dictionnaires de données pour les inferter, mais le SQL est toujours explicite.

C'est pourquoi vous voyez que, dans la pratique, en SQL, toutes les jointures sont explicites.

dans la pratique, les bases de données sans contraintes FK ont tendance à avoir des problèmes d'intégrité, puisqu'il n'y a pas de contrainte pour exiger la clé exister. Donc c'est certainement plus pratique d'avoir autant de contraintes que possible - il protège l'intégrité et permet à l'optimiseur et les autres utilisateurs. Comme pour toute pratique exemplaire, il est également important de savoir quand (si jamais) enfreindre la règle.

quant à savoir pourquoi vous pouvez faire une jointure qui ne correspond pas à une contrainte clé étrangère entre ces tables, il y a une myriade d'exemples. En particulier dans le cas de clés en composite avec jointures partielles, je trouve que cela est souvent nécessaire. Nous avons souvent rejoignez sur les tables en utilisant des versions partielles de leurs clés primaires dans le stockage de données.

vous pouvez également être intéressé par cet article sur l'élimination de clé étrangère jointure par l'optimizer.

-1
répondu Cade Roux 2009-12-10 05:58:27

clé Étrangère est couplage . Dans la programmation, le couplage est rarement bon.

-1
répondu datasn.io 2015-09-04 02:47:53