Différence entre une jointure thêta, une équi-jointure et une jointure naturelle


95

J'ai du mal à comprendre l'algèbre relationnelle en ce qui concerne les jointures thêta, les équi-jointures et les jointures naturelles. Quelqu'un pourrait-il m'aider à mieux le comprendre? Si j'utilise le signe = sur une jointure thêta, est-ce exactement la même chose que d'utiliser une jointure naturelle?


concernant la citation en question de la prime ... il ne cite pas Codd ici, il cite ma réponse sous laquelle son commentaire apparaît.
heisenberg

Réponses:


141

Une jointure thêta permet des relations de comparaison arbitraires (telles que ≥).

Une équi - jointure est une jointure thêta utilisant l'opérateur d'égalité.

Une jointure naturelle est une équi-jointure sur des attributs qui ont le même nom dans chaque relation.

En outre, une jointure naturelle supprime les colonnes en double impliquées dans la comparaison d'égalité de sorte qu'il ne reste qu'une seule colonne de chaque colonne comparée; en termes algébriques relationnels approximatifs: ⋈ = πR,S-as ○ ⋈aR=aS


13
la jointure naturelle supprimera les colonnes du même nom
Bogdan Gavril MSFT

2
Tous, ou tous sauf un?
Christopher Shroba

Equijoin supprimera également la colonne d'égalité si elles ont le même nom dans les deux tables.
Vishal R

1
@outis, Que signifie "theta" dans "theta join"?
Pacerier

2
@Pacerier: Historiquement, la thetajointure in thêta fait référence à une condition arbitraire utilisée comme critère pour la jointure. (voir Database Systems: The Complete Book par Garcia-Molina, Ullman, Widom, chapitre 2, Theta Join)
Ram Rajamony

57

Bien que les réponses expliquant les différences exactes soient correctes, je veux montrer comment l'algèbre relationnelle est transformée en SQL et quelle est la valeur réelle des 3 concepts.

Le concept clé de votre question est l'idée d'une jointure. Pour comprendre une jointure, vous devez comprendre un produit cartésien (l'exemple est basé sur SQL où l'équivalent est appelé une jointure croisée comme onedaywhen fait remarquer);

Ce n'est pas très utile en pratique. Prenons cet exemple.

Product(PName, Price)
====================
Laptop,   1500
Car,      20000
Airplane, 3000000


Component(PName, CName, Cost)
=============================
Laptop, CPU,    500
Laptop, hdd,    300
Laptop, case,   700
Car,    wheels, 1000

Le produit cartésien Product x Component sera - ci-dessous ou sql violon . Vous pouvez voir qu'il y a 12 lignes = 3 x 4. Evidemment, les lignes comme "Laptop" avec "roues" n'ont aucun sens, c'est pourquoi en pratique le produit cartésien est rarement utilisé.

|    PNAME |   PRICE |  CNAME | COST |
--------------------------------------
|   Laptop |    1500 |    CPU |  500 |
|   Laptop |    1500 |    hdd |  300 |
|   Laptop |    1500 |   case |  700 |
|   Laptop |    1500 | wheels | 1000 |
|      Car |   20000 |    CPU |  500 |
|      Car |   20000 |    hdd |  300 |
|      Car |   20000 |   case |  700 |
|      Car |   20000 | wheels | 1000 |
| Airplane | 3000000 |    CPU |  500 |
| Airplane | 3000000 |    hdd |  300 |
| Airplane | 3000000 |   case |  700 |
| Airplane | 3000000 | wheels | 1000 |

Les JOIN sont là pour ajouter plus de valeur à ces produits. Ce que nous voulons vraiment, c'est «joindre» le produit avec ses composants associés, car chaque composant appartient à un produit. La façon de faire est avec une jointure:

Produit JOIN Component ON Pname

La requête SQL associée serait comme ceci (vous pouvez jouer avec tous les exemples ici )

SELECT *
FROM Product
JOIN Component
  ON Product.Pname = Component.Pname

et le résultat:

|  PNAME | PRICE |  CNAME | COST |
----------------------------------
| Laptop |  1500 |    CPU |  500 |
| Laptop |  1500 |    hdd |  300 |
| Laptop |  1500 |   case |  700 |
|    Car | 20000 | wheels | 1000 |

Notez que le résultat n'a que 4 lignes, car l'ordinateur portable a 3 composants, la voiture en a 1 et l'avion aucun. C'est beaucoup plus utile.

Pour revenir à vos questions, toutes les jointures que vous demandez sont des variations du JOIN que je viens de montrer:

Jointure naturelle = la jointure (la clause ON) est faite sur toutes les colonnes avec le même nom; il supprime les colonnes dupliquées du résultat, contrairement à toutes les autres jointures; la plupart des SGBD (systèmes de bases de données créés par divers fournisseurs tels que SQL Server de Microsoft, MySQL d'Oracle, etc.) ne prennent même pas la peine de supporter cela, c'est juste une mauvaise pratique (ou ont délibérément choisi de ne pas l'implémenter). Imaginez qu'un développeur vienne et modifie le nom de la deuxième colonne dans Product de Price en Cost. Ensuite, toutes les jointures naturelles seraient effectuées sur PName ET sur Cost, ce qui donnerait 0 lignes car aucun nombre ne correspond.

Theta Join = c'est la jointure générale que tout le monde utilise car elle vous permet de spécifier la condition (la clause ON en SQL). Vous pouvez rejoindre à peu près toutes les conditions de votre choix, par exemple sur des produits dont les 2 premières lettres sont similaires ou qui ont un prix différent. En pratique, c'est rarement le cas - dans 95% des cas, vous rejoindrez une condition d'égalité, ce qui nous conduit à:

Equi Join = le plus couramment utilisé dans la pratique. L'exemple ci-dessus est une jointure équi. Les bases de données sont optimisées pour ce type de jointures! L'oposite d'une jointure équi est une jointure non équi, c'est-à-dire lorsque vous joignez une condition autre que "=". Les bases de données ne sont pas optimisées pour cela! Les deux sont des sous-ensembles de la jointure thêta générale. La jointure naturelle est également une jointure thêta mais la condition (la thêta) est implicite.

Source d'information: université + développeur certifié SQL Server + a récemment terminé le MOO "Introduction aux bases de données" de Stanford donc j'ose dire que j'ai une nouvelle algèbre relationnelle à l'esprit.


1
Vous utilisez le terme «produit cartésien» de manière assez vague. Le produit opérateur relationnel aboutit à une relation (en commun avec tous les opérateurs relationnels!) Une CROSS JOINopération en SQL aboutit à une expression de table (lignes de colonnes). L'opération d'ensemble produit cartésien donne un ensemble de paires.
jour du

1
Lorsque vous dites «bases de données», vous voulez dire en fait «SGBD», une différence cruciale pour aborder les «concepts».
jour du

2
un jour quand - merci pour tous les commentaires utiles! ressemble à une révision de code :). J'ai corrigé les problèmes de produit cartésien et de SGBD. Je maintiens mon opinion que les jointures naturelles n'ont qu'un intérêt académique et que les SGBD importants tels que SQL Server ne l'implémentent pas exprès - l'ajout d'une condition conduit explicitement à une meilleure compréhension et maintenance du code. Une question connexe: stackoverflow.com/questions/4826613/natural-join-in-sql-server
Bogdan Gavril MSFT

1
@HLGEM: on pourrait faire des arguments similaires contre SELECT * FROM...(et peut-être que vous le faites). Mais c'est dans le langage, c'est dans toutes les implémentations SQL et je l'utilise souvent (et je parie que vous le faites aussi!) Indice que tout le code n'est pas du code de production.
jour du

1
Le vrai problème avec une colonne jointe «naturelle» n'est pas de changer les noms mais d'en ajouter de nouveaux qui ne doivent pas entrer en conflit entre toutes les tables éventuellement jointes dans le système. Prenez des colonnes très courantes telles que "nom", "description", ... L'utilisation de "jointure naturelle" les rendra jointes alors que cela n'a aucun sens et que plus est contraire à la logique métier et conduit à l'erreur. Alors oui, la "jointure naturelle" est dangereuse. Cela vous oblige à avoir des noms distincts à l'exception des colonnes de clé (primaire / étrangère) et à perdre "l'espacement des noms".
LoganMzz

14

La réponse de @ outis est bonne: concise et correcte en ce qui concerne les relations.

Cependant, la situation est légèrement plus compliquée en ce qui concerne SQL.

Considérez la base de données habituelle des fournisseurs et des pièces mais implémentée en SQL:

SELECT * FROM S NATURAL JOIN SP;

renverrait un jeu de résultats ** avec des colonnes

SNO, SNAME, STATUS, CITY, PNO, QTY

La jointure est effectuée sur la colonne avec le même nom dans les deux tables, SNO. Notez que l'ensemble de résultats comporte six colonnes et ne contient qu'une seule colonne pour SNO.

Considérons maintenant une eqijoin thêta, où les noms de colonne pour la jointure doivent être explicitement spécifiés (plus les variables de plage Set SPsont obligatoires):

SELECT * FROM S JOIN SP ON S.SNO = SP.SNO;

L'ensemble de résultats comportera sept colonnes, dont deux pour SNO. Les noms de l'ensemble de résultats correspondent à ce que la norme SQL appelle "dépendant de l'implémentation", mais pourraient ressembler à ceci:

SNO, SNAME, STATUS, CITY, SNO, PNO, QTY

ou peut-être ceci

S.SNO, SNAME, STATUS, CITY, SP.SNO, PNO, QTY

En d'autres termes, NATURAL JOINen SQL peut être envisagé de supprimer les colonnes avec des noms en double du jeu de résultats (mais hélas ne supprimera pas les lignes en double - vous devez vous rappeler de changer SELECTpour SELECT DISTINCTvous-même).


** Je ne sais pas trop quel est le résultat SELECT * FROM table_expression;. Je sais que ce n'est pas une relation car, entre autres raisons, il peut avoir des colonnes avec des noms en double ou une colonne sans nom. Je sais que ce n'est pas un ensemble car, entre autres raisons, l'ordre des colonnes est important. Ce n'est même pas une table SQL ou une expression de table SQL. J'appelle cela un ensemble de résultats.


Il en va de même JOIN ... USING(...).
Benoit

Pourquoi dites-vous "Je ne sais pas trop de quoi il en résulte SELECT * FROM table_expression;" ?
Pacerier

@Pacerier: euh, parce que je ne sais pas ce que c'est! La dernière fois que j'ai regardé, le SQL Standard a évité de définir ce que c'était. Je sais ce que ce n'est pas (pas une relation, pas un ensemble, pas une table, pas une expression de table). Donc, pour plus de commodité, j'ai utilisé mon propre terme, «resultset». Notez que dans le modèle relationnel, le résultat d'une opération impliquant deux relations est une relation. L'instruction équivalente ne peut pas être faite pour SQL AFAIK.
jour du

11

Natural est un sous-ensemble d'Equi qui est un sous-ensemble de Theta.

Si j'utilise le signe = sur une jointure thêta, est-ce exactement la même chose que d'utiliser une jointure naturelle ???

Pas nécessairement, mais ce serait un Equi. Naturel signifie que vous correspondez sur toutes les colonnes de nom similaire, Equi signifie simplement que vous utilisez '=' exclusivement (et pas 'moins que', comme, etc.)

Cependant, il s'agit d'un pur milieu universitaire, vous pouvez travailler avec des bases de données relationnelles pendant des années et ne jamais entendre personne utiliser ces termes.


Je soupçonne que lorsque vous dites "bases de données relationnelles", je soupçonne que vous voulez dire autre chose, par exemple "SQL".
jour du

Un travail qui n'est pas universitaire avec des bases de données relationnelles qui ne sont pas SQL? Alors de quels produits parlez-vous?
jour du

3
Dans l'algèbre originale de Codd, la jointure naturelle est le type fondamental de jointure alors qu'une équi- ou théta- "jointure" est un raccourci pour un NJ (par exemple, produit croisé) suivi d'une restriction. "Natural est un sous-ensemble d'Equi qui est un sous-ensemble de Theta" ce que cela signifie probablement est que chaque NJ pourrait également être exprimé comme un EJ ou TJ. Je suppose que c'est vrai si σ 1 = 1 (A x B) compte comme une équi-jointure, auquel cas chaque opération de l'algèbre relationnelle pourrait être exprimée comme une équi-jointure sous cette forme. L'ambiguïté ici est qu'il existe plusieurs ensembles possibles d'opérateurs fondamentaux pour la RA.
nvogel

2
@EricFail: sqlvogel cite simplement la réponse de kekekela, plutôt que quoi que ce soit de Codd. Si vous voulez en savoir plus sur les écrits de Codd sur les jointures (θ ou autre), vous pouvez essayer "Le modèle relationnel pour la gestion de base de données", ou parcourir sa bibliographie .
sort

1
... La question à laquelle vous créez un lien a une réponse qui se rapproche de ce que vous recherchez, probablement aussi proche que possible. Il est lié à l' exhaustivité relationnelle des sous-langues de la base de données . P. 10 décrit la connexion entre θ, = et les jointures naturelles (bien que naturelles ne soient pas strictement des sous-ensembles de = dans la formulation de Codd, mais plutôt la projection de = -joins).
sortie

7

Jointure thêta: lorsque vous effectuez une requête de jointure à l'aide de n'importe quel opérateur (par exemple, =, <,>,> = etc.), cette requête de jointure relève de la jointure thêta.

Jointure Equi: lorsque vous effectuez une requête de jointure à l'aide de l'opérateur d'égalité uniquement, cette requête de jointure relève de la jointure Equi.

Exemple:

> SELECT * FROM Emp JOIN Dept ON Emp.DeptID = Dept.DeptID;
> SELECT * FROM Emp INNER REJOINDRE Dept UTILISATION (DeptID)
Cela montrera:
 _________________________________________________
| Emp.Name | Emp.DeptID | Dept.Name | Dept.DeptID |
| | | | |

Remarque: la jointure Equi est également une jointure thêta!

Jointure naturelle: un type de jointure Equi qui se produit implicitement en comparant toutes les mêmes colonnes de noms dans les deux tables.

Remarque: ici, le résultat de la jointure n'a qu'une seule colonne pour chaque paire de mêmes colonnes nommées.

Exemple

 SELECT * FROM Emp NATURAL JOIN Dept
Cela montrera:
 _______________________________
| DeptID | Emp.Name | Dept.Name |
| | | |

1

Le produit cartésien de deux tableaux donne toutes les combinaisons possibles de tuples comme l'exemple en mathématiques le produit croisé de deux ensembles. comme il y a souvent des valeurs inutiles qui occupent également un espace inutile dans la mémoire, alors les jointures viennent à la rescousse qui ne donnent la combinaison que des valeurs d'attribut qui sont requises et qui sont significatives.

la jointure interne donne deux fois le champ répété dans la table, tandis que la jointure naturelle résout ici le problème en filtrant simplement les colonnes répétées et en ne l'affichant qu'une seule fois. Sinon, les deux fonctionnent de la même manière. la jointure naturelle est plus efficace car elle préserve la mémoire. De plus, les redondances sont supprimées dans la jointure naturelle.

La jointure equi de deux tables est telle qu'elle n'affiche que les tuples qui correspondent à la valeur d'une autre table. par exemple: laissez new1 et new2 deux tables. si la requête SQL sélectionnez * à partir de new1 join new2 sur new1.id = new.id (id est la même colonne dans deux tables) puis commencez à partir de la table new2 et joignez qui correspond à l'id dans la deuxième table. de plus, les jointures non équi n'ont pas d'opérateur d'égalité qu'elles ont <,>, et entre l'opérateur.

La jointure thêta comprend tous les opérateurs de comparaison, y compris l'égalité et les autres opérateurs de comparaison <,>. quand il utilise l'opérateur d'égalité (=), il est appelé équi join.


0

Jointure naturelle: une jointure naturelle peut être possible lorsqu'il existe au moins un attribut commun dans deux relations.

Jointure thêta: la jointure thêta peut être possible lorsque deux agissent à des conditions particulières.

Equi Join: Equi peut être possible lorsque deux agissent sur des conditions d'équité. C'est un type de jointure thêta.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.