Poly 04 - Langages de Manipulation Relationnels
Poly 04 - Langages de Manipulation Relationnels
Poly 04 - Langages de Manipulation Relationnels
LANGAGES DE MANIPULATION
RELATIONNELS
Le modèle relationnel a été à l'origine proposé avec deux LMDs de base, l'algèbre relationnelle et
le calcul des tuples, équivalents en puissance et qui ont fixé l'ensemble des fonctions que tout LMD
relationnel doit offrir. A partir de ces deux langages, d'autres LMDs ont pu être définis, qui sont
plus conviviaux pour les utilisateurs. En plus des fonctions de l'algèbre ou du calcul, ces LMD
offrent généralement des possibilités de mise à jour de la base de données, et d'emploi, dans les
requêtes, d'expressions arithmétiques et de fonctions d'agrégation telles que cardinalité, somme,
minimum, maximum et moyenne. On dit d'un LMD qu'il est complet s'il offre au moins les mêmes
fonctions que l'algèbre ou le calcul relationnel.
Un autre type de LMD est constitué des langages issus du calcul des prédicats de la logique du
premier ordre. Deux adaptations de ce calcul au modèle relationnel ont été proposées, qui toutes
deux ont conduit à des langages utilisateurs:
- le calcul des tuples, qui a donné naissance au LMD QUEL du SGBD relationnel Ingres,
- le calcul des domaines qui a donné naissance à des LMD de type graphique dont QBE, proposé
par IBM.
Les langages de type prédicatif sont actuellement très prisés par les utilisateurs. Une requête
exprimée dans un tel langage, spécifie par des prédicats uniquement les caractéristiques du résultat
qu'elle veut obtenir (c'est-à-dire la définition du résultat désiré). Tandis que la même requête
exprimée dans un langage algébrique, spécifie un enchaînement d'opérations conduisant au résultat
désiré (c'est-à-dire comment construire le résultat à partir des relations de la base de données).
SQL qui est le LMD relationnel le plus répandu du fait que c'est la seule norme existante
pour les LMD relationnels, comporte des caractéristiques de type algébrique et d'autres de type
prédicatif.
1 Introduction
L’algèbre relationnelle est un ensemble d'opérateurs qui, à partir d'une ou deux relations existantes,
créent en résultat une nouvelle relation temporaire (c'est-à-dire qui a une durée de vie limitée,
généralement la relation est détruite à la fin du programme utilisateur ou de la transaction qui l'a
créée). La relation résultat a exactement les mêmes caractéristiques qu'une relation de la base de
données et peut donc être manipulée de nouveau par les opérateurs de l'algèbre.
Formellement l'algèbre comprend:
- cinq opérateurs de base: sélection, projection, union, différence et produit,
- un opérateur syntaxique, renommer, qui ne fait que modifier le schéma et pas les tuples.
A partir de ces opérateurs, d'autres opérateurs ont été proposés qui sont équivalents à la composition
de plusieurs opérateurs de base. Ces nouveaux opérateurs, appelés opérateurs déduits, sont des
raccourcis d'écriture, qui n'apportent aucune fonctionnalité nouvelle, mais qui sont pratiques pour
l'utilisateur lors de l'écriture des requêtes. Nous présentons dans ce chapitre les opérateurs déduits
les plus fréquents: intersection, jointure naturelle, thêta jointure et division.
2 Les opérateurs
2.1. Projection
Cet opérateur construit une relation résultat où n'apparaissent que certains attributs de la relation
opérande (en termes de tableau, cela revient à extraire certaines colonnes).
Définition : soit R (A1, A2, ...., An) une relation, et soit Ai1, Ai2, ....., Aij un sous-ensemble de ses
attributs, la projection de R sur Ai1, Ai2, ....., Aij, notée :
π [Ai1, Ai2, ....., Aij] R
crée une nouvelle relation, temporaire, de schéma (Ai1, Ai2, ....., Aij) et de population égale à
l'ensemble des tuples de R "tronqués à Ai1, Ai2, ....., Aij ", i.e. :
{t / ∃r (r∈ R ∧ t.Ai1 = r.Ai1 ∧ t.Ai2 = r.Ai2 ∧ .... ∧ t.Aij = r.Aij)}
Remarque: le résultat est un ensemble de tuples sans double, c'est-à-dire que si la projection crée
des tuples en double - cas d'une projection éliminant tous les identifiants de R - ces doubles sont
supprimés automatiquement.
2.2. Sélection
Cet opérateur construit une relation résultat où n'apparaissent que certains tuples de la relation
opérande (en termes de tableau, cela revient à extraire certaines lignes). Les tuples retenus sont
ceux satisfaisant une condition explicite, appelée prédicat de sélection.
Définition: soit R (A1, A2, ...., An) une relation, la sélection de R selon un prédicat p, notée:
σ [p] R
crée une nouvelle relation, temporaire, de schéma identique à celui de R, et de population
l'ensemble des tuples de R pour lesquels le prédicat p est vrai.
Exemple: pour créer une relation Femmes contenant l'ensemble des personnes de sexe féminin, on
écrira:
Femmes := σ [sexe = 'F'] Personne
Remarquons que les opérateurs de comparaison ≤ , < , > et ≥ ne peuvent être appliqués qu'aux
attributs dont les domaines contiennent des valeurs ordonnées (valeurs numériques, dates, chaînes
de caractères). Les domaines de chaînes de caractères alphabétiques sont triés alphabétiquement,
tandis que les domaines de chaînes de caractères alphanumériques sont triés selon les codes
numériques des caractères. Si le domaine d'un attribut est un ensemble de valeurs non triées, les
seuls opérateurs de comparaison utilisables sont = et ≠ .
Les opérateurs de l'algèbre peuvent être combinés dans des expressions pour exprimer des requêtes
non élémentaires.
Exemple : on obtient la liste des noms et prénoms des hommes nés avant 1975 par l’expression :
H := π [nom, prénom] σ [sexe = 'M' ∧ an-nais < 75] Personne
H nom prénom
Dupont Jean
Martin Régis
Martin Jules
Le même résultat pourrait être obtenu en écrivant deux opérations l'une après l'autre en créant une
relation intermédiaire (dans ce cas il faut nommer les relations intermédiaires):
H1 := σ [sexe = "M" ∧ an-nais < 75] Personne
H := π [nom, prénom] H1
Définition : étant donné deux relations R(X, Y) et S(Y, Z), où X, Y, Z symbolisent soit un attribut,
soit un ensemble d'attributs, et où Y n'est pas vide, la jointure (naturelle) de R et S, notée :
R*S
crée une nouvelle relation temporaire, de schéma (X, Y, Z). La population de R * S est l'ensemble
des tuples <x, y, z> créés par composition d'un tuple <x, y> de R et d'un tuple <y, z> de S, tels que
les deux tuples ont la même valeur pour Y.
Pour les exemples de requêtes d'algèbre, nous utiliserons par la suite la base de données
relationnelle FormaPerm (du chapitre 3).
L'opérateur renommer, noté α, permet de changer le nom d'un (ou plusieurs) attribut d'une relation
R:
α [nom_attr1: nouveau_nom_pour_attr1, … ] R
Cet opérateur est utile avant les jointures s'il y a un problème d'homonymie ou de synonymie, ou
avant les opérations ensemblistes (union, différence, intersection) qui requièrent que les attributs
correspondants aient le même nom.
Définition : soient deux relations R (A1, A2, …, An) et T (B1, B2, …, Bp) n'ayant pas d'attribut de
même nom, la thêta jointure de R et T selon le prédicat p, notée :
R *[p] T
crée une nouvelle relation temporaire de schéma (A1, A2, …, An, B1, B2, …, Bp), et de population
égale à l'ensemble des tuples de R et de T concaténés qui satisfont le prédicat.
Le prédicat est de la même forme que le prédicat d'une sélection, sauf pour les conditions
élémentaires qui comparent un attribut de R à un attribut de T:
<condition>::= nom-attribut-de-R <opérateur de comparaison> nom-attribut-de-T
Exemple: liste des couples de numéros d'étudiants, tels que ces deux étudiants soient nés le même
jour
*/ on crée d'abord une autre relation Etudiant avec des attributs renommés/*
Etudiant2 := α [n°E : n°E2 , dateN : dateN2] π [n°E, dateN] Etudiant
π [n°E, n°E2] (Etudiant *[n°E < n°E2 ∧ dateN = dateN2] Etudiant2 )
On obtient en résultat, d'après la base de données fournie en exemple, une relation vide.
Définition: soient R et S deux relations de même schéma : R (A1, A2, …, An) , S (A1, A2, …, An).
Union : R ∪ S crée une relation temporaire de même schéma et de population égale à l'ensemble
des tuples de R et de ceux de S (avec élimination des doubles éventuellement créés).
Exemples:
Bases de données avancées 2005-2006 5
liste des numéros des personnes qui sont soit enseignant de BD soit étudiant en BD:
/* on crée deux relations temporaires: */
EnsBD := α [n°Ens : n°P] π [n°Ens] σ [nomC="BD"] Cours
On obtient en résultat d'après la base de données fournie en exemple: 2222.
EtudBD := π [n°P] Etudiant * σ [nomC="BD"] Inscrit
On obtient en résultat d'après la base de données fournie en exemple: 5555.
/* Le résultat recherché est: */
EnsBD ∪ EtudBD
On obtient en résultat: 2222, 5555.
liste des numéros des personnes qui n'ont rien à voir avec le cours de BD:
π[n°P] Personne - ( EnsBD ∪ EtudBD )
On obtient en résultat: 1111, 6666, 3333.
liste des numéros des personnes qui sont enseignants et étudiants simultanément (assistants-
doctorants,…) :
( π [n°P] Enseignant ) ∩ ( π [n°P] Etudiant )
On obtient un résultat vide.
Définition : Soient deux relations, R (A1, A2, …, An) et T (B1, B2, …, Bp), n'ayant pas d'attribut de
même nom, alors le produit de R par T, noté R × T, crée une relation temporaire de schéma (A1,
A2, …, An, B1, B2, …, Bp) et de population toutes les concaténations possibles de tuples de R et de
T.
Remarque: La différence entre les opérateurs de théta-jointure et de produit cartésien consiste dans
le fait que dans la thêta-jointure, seules les combinaisons des tuples qui satisfont le prédicat de
jointure apparaissent dans le résultat, tandis que dans le produit toutes les combinaisons de tuples
sont présentes.
Exemple: existe-t-il des personnes dont le nom est le même que celui d'un cours? Donner leurs
noms.
π[nom] σ[nom=nomC] ( Personne × Cours ) avec un produit et une sélection
ou
π[nom] ( Personne ∗[nom=nomC] Cours ) avec une thêta-jointure
Le résultat est une relation vide.
2.9 Division
Définition : Soient deux relations R (A1, …, An) et V (A1, …, Af) (f < n) telles que tous les
attributs de V sont aussi attributs de R, alors la division de R par V, notée :
R/V
crée une nouvelle relation temporaire de schéma (Af+1, Af+2, …, An), et de population égale aux
tuples de R, tronqués à [Af+1, Af+2, …, An], et qui existent dans R concaténés à tous les tuples de V,
c'est-à-dire:
{<af+1, af+2, ..., an> / ∀ <a1, a2, ... af>∈V, ∃ <a1, a2, ... af, af+1, af+2, ..., an>∈R}
Exemple : liste des étudiants qui peuvent s'inscrire au cours de système (c'est-à-dire qui ont réussi
tous les prérequis de ce cours)
- cours prérequis pour système :
ReqSyst := π [nomCprérequis] σ [nomC = "système"] Prérequis
Cette relation ReqSyst contient alors deux tuples: algo, C.
- numéros des étudiants qui peuvent s'inscrire au cours de système :
( π [nomC, n°E] Obtenu ) / ( α[nomCprérequis : nomC] ReqSyst )
On obtient en résultat un tuple: 22.
Exemple : noms des étudiants qui suivent un des cours de l'enseignant numéro 3333.
La méthode consiste à représenter visuellement la requête sur le schéma des relations. Elle
comprend les étapes suivantes :
1. identifier les relations utiles pour exprimer la requête. Dans l'exemple, ce sont :
Personne pour le nom de l'étudiant,
Cours pour les cours de l'enseignant numéro 3333,
Inscrit et Etudiant pour faire le lien entre ces deux premières relations.
Cette méthode est valable pour la plupart des requêtes. Cependant, certains types de requêtes
nécessitent de compliquer la méthode. C'est le cas des requêtes où la même relation est utilisée
plusieurs fois avec des ensembles de tuples différents. Par exemple : liste des noms des étudiants
qui habitent dans la même ville que l'étudiant Jean Dupont. Ici la relation Etud doit être représentée
par son schéma deux fois, une fois pour Jean Dupont, une fois pour les étudiants recherchés. Enfin,
les requêtes qui comportent l'équivalent sémantique d'un "pour tout" ou d'un "aucun" se
représentent difficilement visuellement.
Intersection :
R ∩ S = R - (R - S) = S - (S - R) ou
R ∩ S = (R ∪ S) - ((R - S) ∪ (S - R))
Jointure naturelle :
Soient R (X,Y) et S (Y,Z)
R * S = π [X,Y,Z] σ [Y = Y'] ( R × α[Y : Y']S )
Thêta jointure :
Soient R (X,Y) et S (U,V)
R *[p] S = σ [p] ( R × S )
Division :
Soient R (X,Y) et S (Y)
R/S = π [X] R - π [X] ( ( ( π[X]R ) × S ) - R )
On remarque que dans le cas du produit cartésien (qui peut être vu comme une théta-jointure sans
condition) la taille du résultat est exactement égale à card (R) x card (S).
On a intérêt à faire "petites" jointures (i.e., qui portent sur des relations avec peu de tuples); sinon
on peut obtenir en résultat une relation énorme! Dans les expressions optimisées d'algèbre, les
sélections seront faites le plus tôt possible. Elles porteront autant que possible sur les relations de la
base de données (et pas sur les jointures).
L'optimisation des requêtes sera traitée plus en détail dans un chapitre ultérieur.
Soient deux ensembles d'attributs tels que: {Ai1, Ai2, ....., Aij} ⊆ {Ak1, Ak2, ....., Akl} ,
alors:
π [Ai1, Ai2, ....., Aij] (π [Ak1, Ak2, ....., Akl] R) = π [Ai1, Ai2, ....., Aij] R
Commutativité:
Bases de données avancées 2005-2006 9
Jointure naturelle:
R*S=S*R
Thêta-jointure:
R *[p] S = S *[p] R
Produit cartésien:
R×S=S×R
Associativité:
Jointure naturelle: si les relations R et S ont au moins un attribut commun, et si les relations R et T
ont au moins un attribut commun, alors:
(R * S) * T = S * (R * T)
Thêta-jointure: si les relations R, S et T n'ont aucun attribut commun, alors:
(R *[p1] S) *[p2] T = S *[p1] (R *[p2] T)
Produit cartésien: si les relations R, S et T n'ont aucun attribut commun, alors:
(R × S) × T = S × (R × T)
Les opérateurs d'union et d'intersection sont commutatifs et associatifs. Ces propriétés sont
directement dérivées de la théorie des ensembles. Par contre, l'opérateur de différence n'est ni
associatif ni commutatif.
1. Introduction
Avec l’algèbre relationnelle, une requête est exprimée comme une séquence d’opérations à réaliser
sur des relations de la base de données. Par contre, l'objectif des langages prédicatifs (ou langages
de type calcul), qui sont inspirés du calcul des prédicats de la logique du premier ordre, est
d'exprimer une requête par la simple définition du résultat, en faisant abstraction du mécanisme
utilisé par le SGBD pour la construction de ce résultat. Ce sont donc des langages déclaratifs.
Les calculs relationnels résultent d'une adaptation du calcul des prédicats à l'interrogation de bases
de données relationnelles. Il en existe deux types : le calcul de tuples et le calcul de domaines,
suivant que les variables utilisées dans les formules du calcul désignent des tuples d'une relation ou
des valeurs dans un domaine. QUEL (pour INGRES) et QBE (IBM) sont des langages
commercialisés dérivés du calcul relationnel (respectivement, de tuples et de domaines).
2. Le calcul de tuples
Une requête dans ce langage est composée de deux parties : une partie déclarative et une expression
du calcul :
- La partie déclarative associe des variables aux relations de la BD qui sont utilisées dans la
requête:
x∈R : x désignera les tuples de la relation R (“x porte sur R”);
y∈S∪T : y désignera indifféremment les tuples des relations S et T, pourvu qu'il existe
dans S et T des attributs qui soient compatibles deux à deux (même nom, même
domaine);
- L'expression a la forme : {x.A, y.B,..., z.D / fx, y,..., z, t, u,…., w}
où x, y,..., z, t, u, …, w sont des variables dont la portée a été déclarée auparavant: x∈R1,
y∈R2, ..., z∈Ri, t∈Rj, ..., w∈Rn,
A, B,..., D sont des attributs des relations correspondantes,
fx,y,...,z,t,…,w est une formule valide (voir ci-dessous) ayant pour variables libres x, y,...z, et
pour variables liées t, u, …,w.
La valeur de cette expression est une projection sur les attributs A,B,...,D du produit cartésien des
relations correspondantes aux variables libres R1 ×R2 × ... ×Ri, produit réduit aux tuples pour
lesquels la formule fx,y,...,z,t,…,w est vraie.
Exemples : soit une base de données avec les trois relations suivantes:
Etudiant (nom, prénom, année de naissance, n°étudiant)
Inscription (n°étudiant, nom cours, note1, note2)
Enseignant (nom, prénom, statut)
Requête : numéro, prénom et notes des étudiants de nom Dupont inscrits au cours BD
e ∈ Etudiant, i ∈ Inscription
{e.n°étudiant, e.prénom, i.note1, i.note2 / e.nom = 'Dupont'
∧ e.n°étudiant = i.n°étudiant ∧ i.nom cours = 'BD'}
Définition: Une variable est dite liée (quantifiée) dans une formule si elle est associée au
quantificateur existentiel, ∃, ou au quantificateur universel,∀. Elle est dite libre sinon.
La dernière formule peut être utilisée, par exemple, pour retrouver les étudiants ayant brillamment
réussi dans un cours (les deux notes pour ce cours sont égales à 6):
e∈Etudiant, i∈Inscription;
{e.nom,e.prénom / ∃i (e.n°étudiant = i.n°étudiant ∧ i.note1 = 6 ∧ i.note2 = 6)}
Pour connaître les étudiants qui ont brillamment réussi tous leurs cours, on utilisera l'expression:
{e.nom,e.prénom / ∀i (e.n°étudiant ≠ i.n°étudiant ∨ (i.note1 = 6 ∧ i.note2 = 6)) ∧
∃i (e.n°étudiant = i.n°étudiant)}
1 Le symbole ¬ représente la négation (NOT); le symbole ∧ la conjonction (AND); le symbole ∨ la disjonction (OR).
2 ∃x signifie "il existe un x tel que"; ∀x signifie "quelque soit x"
Bases de données avancées 2005-2006 12
On peut montrer que le calcul de tuples peut exprimer tous les opérateurs de l'algèbre et vice-versa.
Ces deux langages ont la même puissance d'expression.
La clause INTO provoque le rangement du résultat dans une relation temporaire. L'utilisation de
[nouveaunom=] permet de renommer les attributs dans le résultat.
Il n'y a pas de quantificateurs explicites dans QUEL, qui utilise la règle suivante: toutes les
variables apparaissant dans la formule et non citées dans la liste qui suit le RETRIEVE sont
implicitement quantifiées par ∃.
QUEL n'offre pas la possiblité d'utiliser le quantificateur universel ∀. Il est néanmoins possible
d'obtenir le même effet qu'un ∀, en utilisant la fonction d'agrégation COUNT. ∀x (fx) peut s'écrire
en QUEL:
COUNT (x.A WHERE ¬fx) = 0,
ou bien en effectuant l'équivalent de la différence de l'algèbre (voir l'exemple des étudiants ayant
réussi tous leurs cours au paragraphe suivant).
En conclusion, la formule qui suit le WHERE est une formule valide du calcul de tuples étendue à
la prise en compte des fonctions d’agrégation (voir § 3.3), sous forme prénexe, sans quantificateur
universel (∀), où la déclaration des quantificateurs existentiels (∃ nomvar, ...) est omise, et où les
connecteurs logiques s'écrivent : AND (et), OR (ou), NOT (non).
Exemple: lister les noms des étudiants ayant eu au moins une note égale à 10.
Exemple : noms des étudiants ayant brillamment réussi tous leurs cours.
RANGE OF e IS Etudiant
RANGE OF i, i2 IS Inscription
RETRIEVE e.nom WHERE COUNT( i.noétudiant WHERE e.noétudiant = i.noétudiant AND
(i.note1 < 10 OR i.note2 < 10) ) = 0
AND e.noétudiant = i2.noétudiant
En calcul de tuples :
e ∈ Etudiant ∪ Enseignant
{e.nom, e.prénom}
En QUEL :
RANGE OF et IS Etudiant
RANGE OF en IS Enseignant
RETRIEVE INTO EtEns (et.nom, et.prénom)
APPEND TO EtEns (en.nom, en.prénom)
La commande APPEND sert à insérer dans une relation soit un tuple constant, soit un ensemble de
tuples provenant (recopiés) d'une autre relation. Le format général de la commande est:
APPEND TO nom relation ([nomatt1 =] c1, [nomatt2 =] c2, ..., [nomattn =] cn)
[WHERE formule]
où c1, c2, ... , cn sont les valeurs des attributs du ou des tuples à insérer; ces valeurs peuvent être des
constantes ou des expressions. La clause "WHERE formule" est employée dans le cas d'insertion de
tuples provenant d'une autre relation; elle sert à sélectionner l'ensemble des tuples à insérer.
Exemple : liste des noms et des prénoms des étudiants et des enseignants assistants.
RANGE OF et IS Etudiant
RANGE OF en IS Enseignant
RETRIEVE INTO EtEns (et.nom, et.prénom)
APPEND TO EtEns (en.nom, en.prénom) WHERE en.statut = "assistant"
Exemple : noms des étudiants ayant brillamment réussi tous leurs cours.
RANGE OF e IS Etudiant
RETRIEVE INTO Résultat ( n°=e.n°étudiant, nom=e.nom )
RANGE OF i IS Inscription
RANGE OF r IS Résultat
DELETE r WHERE r.n°=i.n°étudiant AND ( i.note1<10 OR i.note2 <10 )
La commande:
Bases de données avancées 2005-2006 14
REPLACE nomvariable (nomattribut1 = expression1, ...) [WHERE formule]
permet de modifier, dans la relation associée à la variable nomvariable, la valeur d'un ou de
plusieurs attributs dans les tuples pour lesquels la formule est vraie.
QUEL permet de calculer des fonctions d'agrégation sur l'ensemble des valeurs prises par un
attribut. Ces fonctions, COUNT, SUM, AVG, MIN et MAX, peuvent être utilisées dans les
formules et dans les expressions des clauses:
RETRIEVE ( [nvnom=] expression , .... )
APPEND TO nomrelation ( nomatt = expression , .... )
REPLACE nomvar ( nomatt = expression , .... ) .
Exemples:
Nombre total d'étudiants
RANGE OF e IS Etudiant
RETRIEVE COUNT(e.n°étudiant)
Remarque: QUEL est complet, c'est-à-dire qu'il permet d'exprimer toute requête d'algèbre ou du
calcul (voir la démonstration par exemple dans le livre de Ullman).
4. Le calcul de domaines
Il est similaire au calcul de tuples, mais les variables portent sur les valeurs d'un attribut (et non sur
les tuples d'une relation).
La partie déclarative d'une requête a la forme suivante :
x ∈ R.A ou x ∈ R.A. ∪ S.B ∪ ....
L'expression a la forme :
{x,y,...,z / fx,y...,z}
où f est une formule valide dont les seules variables libres sont x, y, ..., z.
Les formules valides sont définies de la même façon qu'en calcul de tuples, à ceci près que les
formules élémentaires sont de deux types:
- x1 θ x2 ou x1 θ a où a est une constante, et x1 et x2 sont des variables,
- formules d'appartenance: R(A:v1, B:v2,...), où A,B,... sont des attributs de la relation R, et
v1,v2,... sont soit des constantes, soit des variables. Une condition d'appartenance R(A:v1,
B:v2, ..., E:vi) est vraie ssi dans la relation R il existe au moins un tuple ayant v1 comme
valeur pour l'attribut A, v2 comme valeur pour l'attribut B, ..., et vi comme valeur pour
l'attribut E.
Exemples :
d) noms et prénoms des étudiants ayant brillamment réussi tous leurs cours :
n∈ Etudiant.nom, p∈ Etudiant.prénom, no∈ Etudiant.noétudiant ∪ Inscription.noétudiant,
c∈ Inscription.nom cours
{n,p / ∃no (Etudiant (nom:n, prénom:p, noétudiant:no) ∧
∀c(¬Inscription (noétudiant:no, nom cours:c) ∨
Inscription (noétudiant:no, nom cours:c, note1:10, note2:10))
Bases de données avancées 2005-2006 16
∧ ∃c (Inscription (noétudiant:no, nom cours : c)))}
On peut montrer que le calcul des domaines peut exprimer tous les opérateurs de l'algèbre et vice-
versa.
Une déclaration explicite de toutes les variables n'est pas nécessaire : les éléments qui composent la
requête étant inscrits dans les colonnes correspondantes, ceci définit implicitement leur portée.
5.1 Interrogation
Le format du résultat (la projection finale) d'une requête d'interrogation est spécifié en inscrivant la
commande P. (pour Print) dans les colonnes voulues.
Les conditions du type "nom.variable θ constante" sont spécifiées en écrivant simplement:
θ constante
dans la colonne correspondante (si θ est omis, = est implicite).
Pour exprimer des conditions entre variables (nomvariable1 θ nomvariable2) ou le fait que la même
variable doit apparaître en plusieurs endroits avec la même valeur (Etudiant (noétudiant : no) ∧
Inscription (noétudiant : no)), QBE utilise des "valeurs exemple", soulignées (déclaration explicite
de variable).
Ainsi la requête "numéros et prénoms des étudiants de nom DUPONT qui sont inscrits en BD"
s'écrit:
La répétition de la même valeur exemple (123456) dans les deux colonnes noétudiant équivaut à
spécifier une jointure naturelle entre les deux relations.
Les conditions sont implicitement liées par QBE avec un connecteur logique ET. Un connecteur
OU est exprimé en écrivant deux requêtes.
Exemple: numéros des étudiants ayant mieux réussi en BD à la seconde épreuve qu'à la première.
Conditions
8 < 10
Cette dernière relation (sans nom) est la relation résultat créée par l'utilisateur. (L'utilisateur n'est
pas requis de mettre des noms aux attributs de la relation résultat.). La commande P. indiquée dans
l'entête de la ligne signifie que toute la ligne doit être affichée en résultat.
Quantificateurs: Toutes les variables qui ne font pas partie du résultat sont implicitement
quantifiées par ∃. Le quantificateur universel (∀) peut être simulé soit par des négations, soit par
l'emploi du mot clé ALL qui permet de manipuler l'ensemble des valeurs prises par un attribut (voir
ci-dessous).
Exemple : noms et prénoms des étudiants ayant brillamment réussi tous leurs cours.
On peut écrire cette requête à l'aide d'une négation par note: il n'existe pas, pour cet étudiant, de
tuple avec une note inférieure à 10.
Définition: la négation (¬) notée en face d'un tuple d'une relation R signifie: il n'existe pas dans R
de tuple satisfaisant les conditions indiquées.
On peut aussi employer le mot clé ALL qui définit un "multi-ensemble" (ensemble avec des
doubles éventuels) de valeurs, auquel on peut donner un nom de variable en faisant suivre le mot
clé "ALL." d'un nom exemple. La requête précédente s'écrit :
Doubles:
QBE supprime implicitement les doubles du résultat. Pour les conserver, il faut spécifier
ALL.nomvariable dans la colonne correspondante.
Exemple: liste des noms des étudiants
Tri:
On peut aussi demander un résultat trié, en spécifiant l'ordre (AO: ascending order, DO: descending
order) avec le nom de la variable.
Exemple: liste ordonnée des noms des étudiants
Fermeture transitive:
Si une relation est cyclique, QBE permet la recherche par transitivité.
Exemple: la requête:
permet de retrouver les cours qui sont prérequis pour les cours prérequis par le cours BD.
Cette même requête peut s'écrire en utilisant le mot clé L (pour Level) qui, associé à un entier,
spécifie le nombre de niveaux de transitivité à parcourir (2 dans cet exemple):
La recherche de la fermeture transitive (tous les prérequis d'un cours à quelque niveau que ce soit)
est spécifiée en remplaçant la constante entière par une variable exemple:
Cette possibilité de calculer la fermeture transitive est particulière à QBE, qui est un des rares
langages commercialisés à l'offrir.
Fonctions d'agrégation:
Les fonctions d'agrégation classiques (COUNT, SUM, AVG, MAX, MIN) peuvent être utilisées,
associées à une variable précédée de ALL. Si les doubles ne doivent pas être pris en compte par la
fonction, on spécifiera UNQ (unique) avant le mot clef ALL. L'opérateur UNQ transforme un
multi-ensemble en un ensemble en supprimant les doubles.
Exemple : nombre d'étudiants par année de naissance
QBE offre trois commandes pour la mise à jour des relations : I. (insert), U. (update), D. (delete), à
spécifier sous le nom de la relation.
L'insertion d'un nouveau tuple se fait en donnant les valeurs qui composent le tuple :
Lors de la modification de la valeur d'un (ou plusieurs) attribut, il faut définir dans quels tuples elle
doit avoir lieu en précisant la valeur de l'identifiant des tuples à modifier (la déclaration d'une
relation en QBE comprend la définition de l'identifiant). Les attributs faisant partie de l'identifiant
ne sont pas modifiables.
Exemple : entrer 10 pour la note2 de BD de l'étudiant numéro 3333 (la note1 n'est pas modifiée).
Dans ce cas, la valeur de l'identifiant est connue: 3333 + BD .
Exemple : augmenter d'un demi-point toute note1 inférieure à 10 pour le cours BD.
Dans ce cas, la valeur de l'identifiant n'est pas entièrement connue. Elle doit être définie dans une
(des) autre ligne non préfixée par la commande U.
La suppression d'un ou plusieurs tuples d'une relation se fait en spécifiant le critère de sélection.
Par exemple, la commande suivante:
De la même façon que pour la commande U., la définition du (des) tuples à modifier peut être faite
à l'aide d'autres lignes non préfixées par D.
Le système crée une variable tuple pour chaque ligne de la requête qui porte sur une relation de la
base (pas pour la relation résultat créée par l'utilisateur si elle existe).
Le système crée un programme avec des boucles d'itération emboitées, une par variable tuple, la
variable balayant toute la relation correspondante. A chaque pas de l'itération, le système teste si les
valeurs des tuples référencés par les variables satisfont la requête. Si oui, les commandes indiquées
dans la requête (P., U., D., …) sont exécutées.
En pratique, les SGBDs relationnels fournissant QBE ne suivent pas mot à mot ces algorithmes,
mais d'autres, éventuellement plus efficaces, sémantiquement équivalents.