Relation Produit
:
idProduit | nom | prix |
---|---|---|
1 | Clavier | 45 |
2 | Souris | 30 |
3 | Écran | 220 |
1. σ_{prix > 40}(Produit)
2. Résultat :
| idProduit | nom | prix |
|-----------|---------|------|
| 1 | Clavier | 45 |
| 3 | Écran | 220 |
3. σ_{prix ≤ 100}(Produit)
Toujours avec la relation Produit
:
nom
et prix
.idProduit
.1. π_{nom, prix}(Produit)
2. Oui, si plusieurs lignes ont le même nom et prix, elles seront fusionnées.
Exemple : deux produits avec nom = "Souris" et prix = 30 apparaîtront qu’une seule fois.
3. π_{idProduit}(Produit)
Deux relations :
Client(nom)
Prospect(nom)
Client | Prospect | |
---|---|---|
nom | nom | |
Alice | Bernard | |
Bernard | Camille |
1. Client ∪ Prospect
2. Résultat :
| nom |
|---------|
| Alice |
| Bernard |
| Camille |
→ Les doublons sont supprimés automatiquement.
3. L’union n’est possible que si les deux relations ont le **même nombre et ordre de colonnes** (même schéma). Sinon, l’opération est invalide.
Même relations Client(nom)
et Prospect(nom)
:
1. Client − Prospect
2. Résultat :
| nom |
|-------|
| Alice |
→ Alice est cliente mais pas prospecte.
3. Non, la différence n’est pas symétrique :
- Client − Prospect = { Alice }
- Prospect − Client = { Camille }
→ L’ordre est important.
Relations :
Auteurs(nom)
Livres(titre)
1. Auteurs × Livres
2. 2 auteurs × 3 livres = 6 lignes.
3. Le produit cartésien associe tous les auteurs à tous les livres.
→ Ce n’est utile que si on applique ensuite un **filtre** (ex. : "cet auteur a écrit ce livre") pour obtenir des correspondances réelles.
→ Cela donne alors une jointure (produit + sélection).
Relations :
Employe(id, nom, idDept)
Departement(idDept, nomDept)
1. Employe ⨝_{Employe.idDept = Departement.idDept} Departement
2. Une union n’est possible que si les deux relations ont **le même schéma** (mêmes colonnes). Ce n’est pas le cas ici.
3. π_{nom, nomDept}(Employe ⨝_{Employe.idDept = Departement.idDept} Departement)
Relations :
Employe(id, nom, idDept)
Departement(idDept, nomDept)
1. π_{nom}(σ_{nomDept = "RH"}(Employe ⨝_{Employe.idDept = Departement.idDept} Departement))
2. Le filtre porte sur "nomDept", qui n’existe que dans Departement. Il faut donc faire la jointure d’abord pour avoir accès à ce champ dans les résultats.
3. On ne peut pas filtrer sur un champ qui n’existe pas encore dans la relation : il est donc obligatoire de faire la jointure d’abord.
Relations :
EmployeCompetence(employe, competence)
Competence(competence)
Competence
.EmployeCompetence
pour un employé avec seulement une partie des compétences et explique pourquoi il ne sera pas gardé.1. EmployeCompetence ÷ Competence
2. La division permet de **trouver les individus (employés ici) qui ont un lien avec tous les éléments d’un autre ensemble** (toutes les compétences). C’est une recherche globale.
3. Si Competence contient {A, B, C}, et que "Paul" n’a que A et B, il ne sera pas dans le résultat car il n’a **pas toutes** les compétences demandées.
Relations :
Cours(idCours, nomCours)
Inscription(idEtudiant, idCours)
Etudiant(idEtudiant, nom)
1. π_{idEtudiant}(Inscription ÷ π_{idCours}(Cours))
→ puis jointure pour retrouver leur nom :
π_{nom}(Etudiant ⨝_{idEtudiant}(Inscription ÷ π_{idCours}(Cours)))
2. La division est nécessaire ici pour vérifier qu’un étudiant est lié à **toutes les lignes** de la relation Cours.
3. On peut ajouter une relation :
Enseignement(idCours, idProf)
→ Cela permettrait d’associer chaque cours à un enseignant.
Arbre :
π_{nom, prenom}
|
σ_{ville = 'Paris'}
|
Client
1. Étapes :
- On commence avec la relation Client.
- On filtre uniquement les clients dont la ville est "Paris".
- On garde ensuite uniquement les colonnes "nom" et "prenom".
2. Si on projette avant la sélection, on risque de **perdre la colonne "ville"**, donc on **ne pourra plus filtrer**.
3. Conclusion : on doit **toujours garder les colonnes utiles aux filtres** avant de projeter.
Relations :
Commande(idCommande, idClient)
Client(idClient, nom, prenom)
Objectif : afficher le nom et prénom des clients ayant passé une commande.
1. π_{nom, prenom}(Client ⨝_{Client.idClient = Commande.idClient} Commande)
2. Arbre :
π_{nom, prenom}
|
⨝_{Client.idClient = Commande.idClient}
/ \
Client Commande
3. L’opération centrale est la **jointure**, car elle permet d’associer chaque commande à son client.
Relations :
Etudiant(id, nom, prenom)
Inscription(idEtudiant, idCours)
Cours(idCours, nomCours)
Objectif : obtenir le nom des étudiants inscrits au cours "Maths".
1. π_{nom}(Etudiant ⨝ Inscription ⨝ σ_{nomCours = "Maths"}(Cours))
2. Arbre :
π_{nom}
|
⨝ (Etudiant.id = Inscription.idEtudiant)
|
⨝ (Inscription.idCours = Cours.idCours)
|
σ_{nomCours = "Maths"}
|
Cours
(les autres branches : Etudiant et Inscription)
3. Optimisation :
→ Appliquer la sélection sur "Maths" **le plus tôt possible** (directement sur la relation Cours), pour éviter de traiter des données inutiles.
Arbre :
π_{nom}
|
σ_{nomClasse = '2A'}
|
⨝_{Etudiant.idClasse = Classe.idClasse}
/ \
Etudiant Classe
1. Feuilles : Etudiant, Classe
Nœuds internes : jointure, sélection, projection
2. Changer la projection :
π_{nom, prenom}(...)
3. Déplacer ou modifier la sélection :
σ_{prenom = '...'}
→ Elle doit se faire **après la jointure** si le champ est uniquement présent dans Etudiant.
Relations :
Client(id, nom, ville)
Commande(idCommande, idClient, montant)
Objectif : afficher le nom des clients qui habitent à Lyon et ont passé une commande de plus de 1000.
1. Opérations :
- Sélection sur la ville
- Sélection sur le montant
- Jointure entre Client et Commande
- Projection du nom
2. Expression complète :
π_{nom}(σ_{montant > 1000}(Commande) ⨝ σ_{ville = "Lyon"}(Client))
3. Arbre :
π_{nom}
|
⨝ (Client.id = Commande.idClient)
/ \
σ_{ville = "Lyon"} σ_{montant > 1000}
| |
Client Commande