49 votes

Pourquoi sont-clés étrangères plus utilisé dans la théorie que dans la pratique?

Quand vous étudiez la théorie relationnelle des clés étrangères sont, bien entendu, obligatoire. Mais dans la pratique, dans chaque endroit où je travaille, le tableau des produits et des jointures sont toujours fait en spécifiant les touches explicitement dans la requête, au lieu de s'appuyer sur des clés étrangères dans le SGBD.

De cette façon, vous pouvez bien entendu joindre deux tables de champs qui ne sont pas destinés à être des clés étrangères, d'avoir des résultats inattendus.

Pourquoi pensez-vous que c'est? Ne devrait pas Sgbd assurer que les Jointures et des Produits être effectuées uniquement par les clés étrangères?

EDIT: Merci pour toutes les réponses. Il est clair pour moi maintenant que la principale raison pour FKs est la référence de l'intégrité. Mais si vous avez la conception de la base de données, toutes les relations dans le modèle (I. E. les flèches dans la disquette de réparation d'urgence) deviennent des clés Étrangères, au moins en théorie, si oui ou non vous définir comme tels dans votre SGBD, ils sont sémantiquement FKs. Je ne peux pas imaginer la nécessité de joindre des tables de champs qui ne sont pas FKs. Quelqu'un peut-il donner un exemple qui fait sens?

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

39voto

Daniel Vassallo Points 142049

La raison de contraintes de clés étrangères existe, 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 d'une ligne de référence colonnes doivent avoir lieu dans une seule ligne dans la table référencée.

Ainsi, une ligne dans la table de référence ne peut pas contenir de valeurs qui n'existent pas dans la table référencée (sauf éventuellement NULLE). De cette façon, les références peuvent être faites à la liaison d'informations et il est une partie essentielle de normalisation de base de données." (Wikipédia)


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 colonne(s) dans la table de référence doit être la clé primaire de la table référencée, ou au moins une clé candidate.

Quand vous faites des jointures, il n'y a pas besoin de se joindre avec des clés primaires ou candidat clés.

Ce qui suit est un exemple qui pourrait faire 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
);

Et puis la requête 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 sens est dans la base de données géospatiales de fonctionnalités, comme SQL Server 2008 ou Postgres avec PostGIS. Vous serez en mesure 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 en voir un autre similaire géospatiales exemple dans la accepté de répondre à ce poste "Sql 2008 requête problème qui LatLong du existe dans une géographie polygone?":

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 toutes valides jointures SQL qui n'ont rien à voir avec les clés étrangères et candidat clés, et peut encore être utile dans la pratique.

34voto

Otávio Décio Points 44200

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

10voto

Quassnoi Points 191041

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

FOREIGN KEYs ne peut être utilisé pour appliquer l'intégrité référentielle si la relation entre les entités de l' ER modèle se manifeste avec une équi-jointure 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 quelques temps:

Ce modèle décrit les produits et les gammes de prix:

Et voici le relationnel de la mise en œuvre du modèle:

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

Comme vous pouvez le voir, l' PriceRange tableau n'a qu'un seul prix d'attributs, Price, mais le modèle a deux attributs: StartPrice et EndPrice.

C'est parce que le modèle relationnel permet de transformer les décors et l'entité PriceRange peut être facilement reconstitué à l'aide de SQL des opérations.

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 ne disposons que la limite inférieure de chaque plage. La limite supérieure peut être facilement déduite.

Voici la requête pour trouver les bonus pour chaque produit:

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

Nous voyons que ces modèle relationnel met en œuvre le ER modèle assez bien, mais pas de clé étrangère peut être déclarée entre ces relations, depuis l'opération permet de lier entre eux n'est pas une équi-jointure.

8voto

Paul Sonier Points 25528

Non, l'application est inutile; il serait d'interdire à certaines des fonctionnalités utiles, telles que l'éventuelle surcharge de colonnes. Même si ce type d'utilisation n'est pas idéal, il EST utile dans certaines situations du monde réel.

L'utilisation appropriée de contraintes de clé Étrangère est juste comme ça; une contrainte sur les valeurs ajoutées d'une colonne donnée, qui assure que leurs lignes référencées existent.

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

6voto

Bill Karwin Points 204877

Vous pouvez vous joindre à n'importe quelle expression. Si vous définissez les clés étrangères dans votre base de données ou pas est sans importance. Les clés étrangères contraindre INSERT/UPDATE/DELETE, SÉLECTIONNEZ pas.

Alors pourquoi faire beaucoup de projets de sauter la définition des clés étrangères? Il y a plusieurs raisons:

  • Le modèle de données est conçue de façon médiocre et nécessite des références incorrectes (exemples: polymorphe associations, VAE).

  • Les codeurs ont peut-être entendu que "les clés étrangères sont lents", de sorte qu'ils tombent d'eux. En fait, le travail supplémentaire que vous avez à faire pour garantir la cohérence des données lorsque vous ne pouvez pas compter sur les clés étrangères rend votre application beaucoup moins efficace. L'optimisation prématurée, sans réellement mesurer le profit est un problème commun.

  • Les contraintes obtenir de la manière de certaines données des tâches de nettoyage. Parfois, vous avez besoin pour briser les références temporairement comme vous refactoriser de données. De nombreux SGBDR permettre à des contraintes pour les handicapés, mais parfois, les programmeurs de décider qu'il est plus facile de laisser handicapé. Si il y a un besoin fréquent pour désactiver les contraintes, cela indique probablement un brisé conception de base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X