Vous êtes sur la page 1sur 42

Le modèle relationnel 1

BASE DE DONNEES RELATIONNELLES


Préface
Ce document est un support pour les cours en informatique des premières années. La
structure et le contenu des chapitres ont été synchronisés avec le contenu du
programme établi par. Le cours met l'accent sur les concepts et techniques
fondamentaux des bases de données relationnelles, ainsi que sur la conception et
l'implémentation de systèmes informatiques élémentaires de gestion.

I. Introduction
Les bases de données sont actuellement au cœur du système d'information des
entreprises. Les systèmes de gestion de bases de données, initialement disponibles
uniquement sur des "mainframes", peuvent maintenant être installés sur tous les
types d'ordinateurs y compris les ordinateurs personnels.
Mais attention, souvent on désigne, par abus de langage, sous le nom "bases de
données" des ensembles de données qui n'en sont pas.

Qu'est-ce donc qu'une base de données ?


Que peut-on attendre d'un système de gestion de bases de données ?

C'est à ces questions, entre autres, que cet ouvrage essaie d'apporter des réponses.
Dans un premier temps, et de façon informelle, on peut considérer une Base de
Données (BD) comme une grande quantité de données, centralisées ou non, servant
pour les besoins d'une ou plusieurs applications, interrogeables et modifiables par un
groupe d'utilisateurs travaillant en parallèle.

Quant au Système de Gestion de Bases de Données (SGBD), il peut être vu comme le


logiciel qui prend en charge la structuration, le stockage, la mise à jour et la
maintenance des données ; c'est, en fait, l'interface entre la base de données et les
utilisateurs ou leurs programmes.

Les limites à l'utilisation des fichiers


L’utilisation de fichiers impose d'une part, à l'utilisateur de connaître l'organisation
(séquentielle, indexée, ...) des fichiers qu'il utilise afin de pouvoir accéder aux
informations dont il a besoin et, d'autre part, d'écrire des programmes pour pouvoir
effectivement manipuler ces informations. Pour des applications nouvelles,
l'utilisateur devra obligatoirement écrire de nouveaux programmes et il pourra être
amené à créer de nouveaux fichiers qui contiendront peut-être des informations déjà
présentes dans d'autres fichiers.

De telles applications sont :


- Rigides,
- Contraignantes,
- Longues et coûteuses à mettre en œuvre.
Le modèle relationnel 2

Les données associées sont :


- mal définies et mal désignées,
- redondantes,
- peu accessibles de manière ponctuelle,
- peu fiables.

La prise de décision est une part importante de la vie d'une société. Mais elle
nécessite d'être bien informé sur la situation et donc d'avoir des informations à jour
et disponibles immédiatement.
Les utilisateurs, quant à eux, ne veulent plus de systèmes d'information constitués
d'un ensemble de programmes inflexibles et de données inaccessibles à tout non
spécialiste ; ils souhaitent des systèmes d'informations globaux, cohérents,
directement accessibles (sans qu'ils aient besoin soit d'écrire des programmes soit de
demander à un programmeur de les écrire pour eux) et des réponses immédiates aux
questions qu'ils posent. On a donc recherché des solutions tenant compte à la fois des
désirs des utilisateurs et des progrès techniques. Cette recherche a abouti au concept
de base de données.

Définition (base de données) : Une base de données est un ensemble d'informations


sur un sujet qui est :
- exhaustif,
- non redondant,
- structuré,
- persistant.

Définition (système de gestion de base de données) : Un système de gestion de base


de données est un logiciel qui permet de :
- décrire,
- modifier,
- interroger,
- administrer,
les données d'une base de données.

Objectifs des systèmes de gestion de bases de données


Les bases de données et les systèmes de gestion de bases de données ont été créés
pour répondre à un certain nombre de besoins et pour résoudre un certain nombre
de problèmes.
Des objectifs principaux ont été fixés aux systèmes de gestion de bases de données
dès l'origine de ceux-ci et ce, afin de résoudre les problèmes causés par la démarche
classique. Ces objectifs sont les suivants :

Indépendance physique
La façon dont les données sont définies doit être indépendante des structures de
stockages utilisées.
Le modèle relationnel 3

Indépendance logique
Un même ensemble de données peut être vu différemment par des utilisateurs
différents. Toutes ces visions personnelles des données doivent être intégrées dans
une vision globale.

Manipulations des données par des non informaticiens


Il faut pouvoir accéder aux données sans savoir programmer ce qui signifie des
langages "quasi naturels".

Efficacité des accès aux données


Ces langages doivent permettre d'obtenir des réponses aux interrogations en un
temps "raisonnable". Ils doivent donc être optimisés et, entre autres, il faut un
mécanisme permettant de minimiser le nombre d'accès disques. Tout ceci, bien sur,
de façon complètement transparente pour l'utilisateur.

Administration centralisée des données


Des visions différentes des données (entre autres) se résolvent plus facilement si les
données sont administrées de façon centralisée.

Non redondance des données


Afin d'éviter les problèmes lors des mises à jour, chaque donnée ne doit être présente
qu'une seule fois dans la base.

Cohérence des données


Les données sont soumises à un certain nombre de contraintes d'intégrité qui
définissent un état cohérent de la base. Elles doivent pouvoir être exprimées
simplement et vérifiées automatiquement à chaque insertion, modification ou
suppression des données.

Partageabilité des données


Il s'agit de permettre à plusieurs utilisateurs d'accéder aux mêmes données au même
moment. Si ce problème est simple à résoudre quand il s'agit uniquement
d'interrogations et quand on est dans un contexte mono-utilisateur, cela n'est plus le
cas quand il s'agit de modifications dans un contexte multi-utilisateurs. Il s'agit alors
de pouvoir :
 permettre à deux (ou plus) utilisateurs de modifier la même donnée "en même
temps" ;
 assurer un résultat d'interrogation cohérent pour un utilisateur consultant
une table pendant qu'un autre la modifie.

Sécurité des données


Les données doivent pouvoir être protégées contre les accès non autorisés. Pour cela,
il faut pouvoir associer à chaque utilisateur des droits d'accès aux données.
Le modèle relationnel 4

Résistance aux pannes


Que se passe-t-il si une panne survient au milieu d'une modification, si certains
fichiers contenant les données deviennent illisibles? Les pannes, bien qu'étant assez
rares, se produisent quand même de temps en temps. Il faut pouvoir, lorsque l'une
d'elles arrive, récupérer une base dans un état "sain". Ainsi, après une panne
intervenant au milieu d'une modification deux solutions sont possibles : soit
récupérer les données dans l'état dans lequel elles étaient avant la modification, soit
terminer l'opération interrompue.
Malheureusement, ces objectifs ne sont pas toujours atteints.

II. Système de Gestion de Bases de Données


(SGBD)

Définition
Un Système de Gestion de Bases de Données (SGBD) est un logiciel de haut niveau
qui permet de manipuler les informations stockées dans une base de données. La
complexité d’un SGBD est essentiellement issue de la diversité des techniques mises
en œuvre, de la multiplicité des composants intervenant dans son architecture, et des
différents types d’utilisateurs (administrateurs, programmeurs, non
informaticiens, ...) qui sont confrontés, à différents niveaux, au système.
Voici quelques exemples illustrant tous les cas de figure qu’il faudrait envisager dans
un cours exhaustif :
– Les modèles de données : entité-relation, réseau, hiérarchique, relationnel, orienté-
objet, modèles sémantiques.
– Les langages de requêtes : fondements théoriques (logiques du premier ordre, du
point fixe, algèbres diverses) et les langages comme SQL, SQL3, Datalog, OQL, etc.
– Les techniques de stockage : sur disque (optique), sur bande.
– L’organisation des fichiers : index, arbre-B, hachage, ...
– L’architecture : centralisée, distribuée, sur d’autres bases accessibles par réseau.
– Les techniques d’évaluation et d’optimisation de requêtes.
– La concurrence d’accès et les techniques de reprise sur pane.
Pour mettre un peu d’ordre dans tout cela, on peut se raccrocher à une architecture
standard conforme à la plus grande partie des SGBD existant, et offrant l’avantage de
bien illustrer les principales caractéristiques d’un SGBD.
Cette architecture distingue trois niveaux correspondant d’une part à trois
représentations équivalentes de l’information, d’autre part aux champs
d’interventions respectifs des principaux acteurs. Pour ces derniers, nous utiliserons
la terminologie suivante :
– Utilisateur naïf : du non spécialiste des SGBD au non informaticien.
– Concepteur et programmeur d’application : à partir des besoins des différents
utilisateurs, écrit l’application pour des utilisateurs “naïfs”.
– Utilisateur expert : informaticien connaissant le fonctionnement interne d’un SGBD
et chargé d’administrer la base.
Chaque niveau du SGBD remplit (réalise) un certain nombre de fonctions :
Le modèle relationnel 5

 Niveau physiques : gestion sur mémoire secondaire (fichiers) des données, du


schéma, des index ; Partage de données et gestion de la concurrence d’accès ;
Reprise sur pannes (fiabilité) ; Distribution des données et interopérabilité
(accès aux réseaux) ;
 Niveau logique : Définition de la structure de données : Langage de
Description de Données (LDD) ; Consultation et Mise à Jour des données :
Langages de Requêtes (LR) et Langage de Manipulation de Données (LMD) ;
Gestion de la confidentialité (sécurité) ; Maintien de l’intégrité ;
 Niveau externe : Vues ; Environnement de programmation (intégration avec
un langage de programmation); Interfaces conviviales et Langages de 4e
Génération (L4G) ; Outils d’aides (ex. conception de schémas) ; Outils de
saisie, d’impression d’états.

En résumé, un SGBD est destiné à gérer un gros volume d’informations, persistantes


(années) et fiables (protection sur pannes), partageables entre plusieurs utilisateurs
et/ou programmes et manipulées indépendamment de leur représentation physique.

Les opérations sur les données


Il existe 4 opérations classiques (ou requêtes) :
1. La création (ou insertion).
2. La modification (ou mise-à-jour).
3. La destruction.
4. La recherche.
Ces opérations correspondent à des commandes du LMD. La plus complexe est la
recherche en raison de la variété des critères. Pour l’utilisateur, une bonne requête a
les caractéristiques suivantes. Tout d’abord elle s’exprime facilement : l’idéal serait
de pouvoir utiliser le langage naturel, mais celui-ci présente trop d’ambiguïtés.
Ensuite le langage ne devrait pas demander d’expertise technique (syntaxe
compliquée, structures de données, implantation particulière ...). Une bonne partie
du travail sur les SGBD consiste à satisfaire ces besoins. Le résultat est ce que l’on
appelle un langage de requêtes, et constitue à la fois un sujet majeur d’étude et une
caractéristique essentielle de chaque SGBD. Le langage le plus répandu à l’heure
actuelle est SQL.

Optimisation
L’optimisation (d’une requête) s’appuie sur l’organisation physique des données. Les
principaux types d’organisation sont les fichiers séquentiels, les index (denses.
secondaires, arbres B) et le regroupement des données par hachage.
Un module particulier du SGBD, l’optimiseur, tient compte de cette organisation et
des caractéristiques de la requête pour choisir le meilleur séquencement des
opérations.

Concurrence d’accès
Plusieurs utilisateurs doivent pouvoir accéder en même temps aux mêmes données.
Le SGBD doit savoir :
– Gérer les conflits si les deux font des mises-à-jour.
Le modèle relationnel 6

– Offrir un mécanisme de retour en arrière si on décide d’annuler des modifications


en cours.
– Donner une image cohérente des données si l’un fait des requêtes et l’autre des
mises-à-jour.
Le but : éviter les blocages, tout en empêchant des modifications anarchiques.

Le plan du cours
Le cours comprend trois parties consacrées successivement à la conception d’une
base de données relationnelles, aux langages de requêtes relationnels, enfin à la
pratique d’un SGBD relationnel.

III. Conception d’un schéma relationnel


Le cours présente d’abord la technique classique de conception à l’aide du modèle
entité/association, suivie de la transcription du schéma obtenu dans le modèle
relationnel. On obtient un moyen simple et courant de créer des schémas ayant de
bonnes propriétés. Les concepts de ’bon’ et de ’mauvais’ schémas sont ensuite revus
plus formellement avec la théorie de la normalisation.

Langages relationnels
Les langages d’interrogation et de manipulation de données suivants sont présentés :
l’algèbre relationnelle qui fournit un petit ensemble d’opérateurs permettant
d’exprimer des requêtes complexes et le langage SQL, norme SQL2.

Pratique d’un SGBD relationnel


Cette partie reprend et étend les sujets précédents et développe leur mise en pratique
dans l’environnement d’un SGBD relationnel. Elle comprend :
1. Une revue complète du langage de définition de données SQL2 pour la création de
schémas relationnels, incluant l’expression de contraintes, les vues et les triggers.
2. Une introduction au développement d’applications avec SQL.
3. Une introduction à la concurrence d’accès et à ses implications pratiques.
4. Une série de travaux pratiques et d’exercices avec le SGBD Oracle.

Introduction           
"La conception et l'utilisation de bases de données relationnelles sur micro-
ordinateurs n'est pas un domaine réservé aux informaticiens". C'est en tout cas ce
Le modèle relationnel 7

que pensent beaucoup d'utilisateurs en voyant ce type de logiciel intégré aux suites
bureautiques les plus connues.

Cependant la maîtrise d'un SGBDR micro (Système de Gestion de Bases de Données


Relationnelles) est loin d'être aussi facile à acquérir que celle d'un logiciel de
traitement de texte ou d'un tableur.

Plusieurs étapes sont nécessaires à la mise en place d'une base de données, dès lors
que l'on a précisément défini ses besoins (ce qui n'est déjà pas chose facile !) : la
création de la structure de la base sous forme de tables (tableaux de données) reliées
entre elles par des données clés, la conception des requêtes qui permettront
d'extraire ou de mettre à jour les informations qu'elle contient, la conception de
l'interface homme-machine (écrans et états) qui rendra plus conviviale la saisie et la
restitution des informations.

Le degré de difficulté dans la conception de l'interface varie beaucoup selon le


logiciel utilisé qui est d'ailleurs le plus souvent différent du SGBDR.

La conception de la structure de la base de données, si elle est un peu complexe à


appréhender, peut nécessiter, en amont, l'utilisation d'outils de modélisation
conceptuels de type  entités-associations (Modèle Conceptuel des Données de la
méthode MERISE ou diagramme de classes du langage UML). Mais, même dans les
cas les plus simples il faut obligatoirement connaître les concepts du Modèle
Relationnel, sans quoi un utilisateur non averti pourra toujours arriver à créer une
structure inadaptée et sera vite bloqué dans la conception des requêtes.

Il s'agit ici, d'étudier les principaux opérateurs de l'algèbre relationnelle servant de


base à l'élaboration des requêtes.

Bon nombre d'utilisateurs qui voient les matériels informatiques et les logiciels
changer tous les trois mois, seraient surpris d'apprendre que l'algèbre relationnelle a
été définie par Codd en 1970.

Elle est à l'origine du langage SQL (Structured Query Language) d'IBM, langage
d'interrogation et de manipulation de tous les SGBDR actuels (Oracle, Ingres, DB2,
MS SQLServer, MySQL, MS Access et tous les autres).

Elle est également mise en œuvre de manière plus conviviale à travers le langage
QBE (Query By Example) que l'on retrouve seulement sur certains SGBDR (Access
par exemple) et qui n'est pas présenté ici.

Une bonne maîtrise de l'algèbre relationnelle permet de concevoir n'importe quelle


requête aussi complexe soit elle avant de la mettre en œuvre à l'aide du langage QBE
ou SQL.

Parmi les opérations de l'algèbre relationnelle, on dispose d'opérations classiques


sur les ensembles (union, intersection, différence, produit cartésien) puis
d'opérations propres (projection, sélection, jointure, division).
Le modèle relationnel 8

Sont également exposées ici des opérations de calcul, de regroupement, de


comptage et de tri, non définies à l'origine par Codd mais très utiles.

Tous les opérateurs sont présentés à l'aide d'exemples clairs. Pris séparément, ils sont
faciles à appréhender. La rédaction de requêtes (combinaison d'opérateurs) est
illustrée par des exercices concrets.

Le langage SQL n'est abordé que dans le cadre des opérations évoquées ci-dessus.
Seule l'instruction SELECT et ses multiples aspects sont donc présentés.
Le modèle relationnel 9

Le Modèle Relationnel
L'exemple suivant, relatif à la gestion simplifiée des étapes du Tour de France
97, va nous servir à introduire le vocabulaire lié au modèle relationnel.

CodeEquipe NomEquipe DirecteurSportif


BAN BANESTO Eusebio UNZUE
COF COFIDIS Cyrille GUIMARD
CSO CASINO Vincent LAVENU
FDJ LA FRANCAISE DES JEUX Marc MADIOT
FES FESTINA Bruno ROUSSEL
GAN GAN Roger LEGEAY
ONC O.N.C.E. Manolo SAIZ
TEL TELEKOM Walter GODEFROOT
... ... ...

NuméroCoureur NomCoureur CodeEquipe CodePays


8 ULLRICH Jan TEL ALL
31 JALABERT Laurent ONC FRA
61 ROMINGER Tony COF SUI
91 BOARDMAN Chris GAN G-B
114 CIPOLLINI Mario SAE ITA
151 OLANO Abraham BAN ESP
... ... ... ...

NuméroEtape DateEtape VilleDépart VilleArrivée NbKm


1 06-jul-97 ROUEN FORGES-LES-EAUX 192
2 07-jul-97 ST-VALERY-EN-CAUX VIRE 262
3 08-jul-97 VIRE PLUMELEC 224
... ... ... ... ...

 
Le modèle relationnel 10

NuméroCoureur NuméroEtape TempsRéalisé


8 3 04:54:33
8 1 04:48:21
8 2 06:27:47
31 3 04:54:33
31 1 04:48:37
31 2 06:27:47
61 1 04:48:24
61 2 06:27:47
91 3 04:54:33
91 1 04:48:19
91 2 06:27:47
114 3 04:54:44
114 1 04:48:09
114 2 06:27:47
151 3 04:54:33
151 1 04:48:29
151 2 06:27:47
... ... ...
     

CodePays NomPays
ALL ALLEMAGNE
AUT AUTRICHE
BEL BELGIQUE
DAN DANEMARK
ESP ESPAGNE
FRA FRANCE
G-B GRANDE BRETAGNE
ITA ITALIE
P-B PAYS-BAS
RUS RUSSIE
SUI SUISSE
Le modèle relationnel 11

… …
  Comme nous pouvons le constater, le modèle relationnel est un modèle
d'organisation des données sous forme de Tables (Tableaux de valeurs) ou chaque
Table représente une Relation, au sens mathématique d'Ensemble.

C'est ainsi que dans l'exemple présenté, figurent l'ensemble des Equipes, des Coureurs, des
Etapes, des Temps réalisés par les coureurs à chacune des étapes, et enfin l'ensemble des pays.

Les colonnes des tables s'appellent des attributs et les lignes des n-uplets (où n est
le degré de la relation, c'est à dire le nombre d'attributs de la relation).
Un attribut ne prend qu'une seule valeur pour chaque n-uplet.
L'ordre des lignes et des colonnes n'a pas d'importance.

Chaque table doit avoir une clé primaire constituée par un ensemble minimum
d'attributs permettant de distinguer chaque n-uplet de la Relation par rapport à
tous les autres. Chaque ensemble de valeurs formant la clé primaire d'un n-uplet
est donc unique au sein d'une table.

C'est ainsi que dans la table COUREURS, chaque coureur a un NuméroCoureur


différent.

Dans certains cas, plusieurs clés primaires sont possibles pour une seule table. On
parle alors de clés candidates. Il faut alors en choisir une comme clé primaire.

Les liens sémantiques (ou règles de gestion sur les données) existants entre les
ensembles sont réalisés par l'intermédiaire de clés étrangères faisant elles-mêmes
référence à des clés primaires d'autres tables.

C'est ainsi que dans la table COUREURS, la clé étrangère CodeEquipe (faisant
référence à la clé primaire de même nom dans la table EQUIPES) traduit les deux
règles de gestion suivantes :

Un COUREUR appartient à une EQUIPE


Une EQUIPE est composée de plusieurs COUREURS

Il existe deux grands types de liens : Un - Plusieurs (comme le précédent) et


Plusieurs - Plusieurs. La réalisation de ce dernier type de liens, un peu plus
complexe, passe par l'utilisation d'une table intermédiaire dont la clé primaire est
formée des clés étrangères des tables qu'elle relie.

C'est ainsi que la table des TEMPS réalisés à chaque étape par chacun des
coureurs exprime les deux règles de gestion suivantes :

Un COUREUR participe à plusieurs ETAPES


Une ETAPE fait participer plusieurs COUREURS
Le modèle relationnel 12

Le modèle relationnel est le plus souvent décrit sous la forme suivante, les clés
primaires étant soulignées et les clés étrangères marquées par un signe distinctif
(ici *).

EQUIPES (CodeEquipe, NomEquipe, DirecteurSportif)

COUREURS (NuméroCoureur, NomCoureur, CodeEquipe*, CodePays*)

ETAPES (NuméroEtape, VilleDépart, VilleArrivée, NbKm)

TEMPS (NuméroCoureur*, NuméroEtape*, TempsRéalisé)

PAYS (CodePays, NomPays)

On peut aussi le représenter sous forme graphique, de manière à mieux visualiser


et interpréter les liens :

Un COUREUR appartient à une EQUIPE


Une EQUIPE est composée de plusieurs COUREURS

Un COUREUR est originaire d'un PAYS


Un PAYS est représenté par plusieurs COUREURS

Un COUREUR participe à plusieurs ETAPES


Une ETAPE fait participer plusieurs COUREURS

Dans le cadre d'un projet d'informatisation, la conception d'une base de données


relationnelle passe d'abord par l'identification des objets de gestion (Coureurs,
Etapes, …) et des règles de gestion du domaine modélisé (interviews des
utilisateurs, étude des documents manipulés, des fichiers existants, …). Une fois
énoncées et validées, ces règles nous conduisent automatiquement à la structure du
modèle relationnel correspondant.
Le modèle relationnel 13

Opération PROJECTION

Formalisme : R = PROJECTION (R1, liste des attributs)     

  Et en langage SQL
SELECT DISTINCT liste d'attributs FROM table ;
SELECT liste d'attributs FROM table ;

Exemples :
                    
        SELECT DISTINCT Espèce FROM Champignons ;

        SELECT DISTINCT Espèce, Catégorie FROM Champignons ;

 La clause DISTINCT permet d'éliminer les doublons.

Exemples :
                           CHAMPIGNONS

Espèce Catégorie Conditionnement


Rosé des prés Conserve Bocal
Rosé des prés Sec Verrine
Coulemelle Frais Boîte
Rosé des prés Sec Sachet plastique

                    
         R1 = PROJECTION (CHAMPIGNONS, Espèce)

Espèce
Rosé des prés
Coulemelle

                   
                   R2 = PROJECTION (CHAMPIGNONS, Espèce, Catégorie)

Espèce Catégorie
Rosés des prés Conserve
Rosé des prés Sec
Coulemelle Frais
  Cet opérateur ne porte que sur 1 relation.
Il permet de ne retenir que certains attributs spécifiés d'une relation.
On obtient tous les n-uplets de la relation à l'exception des doublons.
Le modèle relationnel 14

Opération SELECTION

Formalisme : R = SELECTION (R1, condition)       

Et en langage SQL

SELECT * FROM table WHERE condition ;

Exemple :

SELECT * FROM Champignons WHERE Catégorie="Sec" ;

La condition de sélection exprimée derrière la clause WHERE peut être spécifiée à l'aide :

des opérateurs de comparaison : =, >, <, <=, >=, <>


des opérateurs logiques : AND, OR, NOT
des opérateurs : IN, BETWEEN, LIKE, IS, ALL

Autres exemples :

Soit la table ETUDIANT(N°Etudiant, Nom, Age, CodePostal, Ville)

SELECT *
FROM ETUDIANT
WHERE Age IN (19, 20, 21, 22, 23) ;

SELECT *
FROM ETUDIANT
WHERE Age BETWEEN 19 AND 23 ;

SELECT *
FROM ETUDIANT
WHERE CodePostal LIKE '42%' ;      // sous Access : LIKE "42*"

SELECT *
FROM ETUDIANT
WHERE CodePostal LIKE '42___' ;    // sous Access : LIKE "42???"

SELECT *
FROM ETUDIANT
WHERE Ville IS NULL ;     // Etudiants pour lesquels la ville n'est pas renseignée

SELECT *
FROM ETUDIANT
WHERE Ville IS NOT NULL ;     // Etudiants pour lesquels la ville est renseignée
Le modèle relationnel 15

SELECT *
FROM ETUDIANT
WHERE Age >= ALL (SELECT Age FROM ETUDIANT) ;     // Etudiant(s) le(s)
plus âgé(s)

 Exemple :
                   CHAMPIGNONS

Espèce Catégorie Conditionnement


Rosé des prés Conserve Bocal
Rosé des prés Sec Verrine
Coulemelle Frais Boîte
Rosé des prés Sec Sachet plastique

                  
                    R3 = SELECTION (CHAMPIGNONS, Catégorie = "Sec")

Espèce Catégorie Conditionnement


Rosé des prés Sec Verrine
Rosé des prés Sec Sachet plastique

Cet opérateur porte sur 1 relation.


Il permet de ne retenir que les n-uplets répondant à une condition exprimée
à l'aide des opérateurs arithmétiques ( =, >, <, >=, <=, <>) ou logiques de
base (ET, OU, NON).
Tous les attributs de la relation sont conservés.
Un attribut peut ne pas avoir été renseigné pour certains n-uplets. Si une
condition de sélection doit en tenir compte, on indiquera simplement :
nomattribut "non renseigné".
Le modèle relationnel 16

Opération JOINTURE (équijointure)

Formalisme : R = JOINTURE (R1, R2, condition d'égalité entre attributs)

Et en langage SQL

En SQL, il est possible d'enchaîner plusieurs jointures dans la même


instruction SELECT.

En SQL de base :

SELECT * FROM table1, table2, table3, ...


WHERE table1.attribut1=table2.attribut1 AND table2.attribut2=table3.attribut2 AND
...;

Exemple :

SELECT * FROM Produit, Détail_Commande


WHERE Produit.CodePrd=Détail_Commande.CodePrd ;

ou en utilisant des alias pour les noms des tables :

SELECT * FROM Produit A, Détail_Commande B


WHERE A.CodePrd=B.CodePrd ;

Avec la clause INNER JOIN (jointure dite interne) à partir du SQL2, supportée
aujourd'hui par tous les SGBDR :

SELECT *
FROM table1 INNER JOIN table2 ON table1.attribut1=table2.attribut1 INNER JOIN
table3 ON table2.attribut2=table3.attribut3... ;

Le mot clé INNER est facultatif sur la plupart des SGBDR (sauf MS Access).

Cette notation rend plus lisible la requête en distinguant clairement les conditions de
jointures, derrière  ON, et les éventuelles conditions de sélection ou restriction,
derrière WHERE.
De plus, l'oubli d'un ON (et donc de la condition de jointure) empêchera l'exécution
de la requête, alors qu'avec l'ancienne notation, l'oubli d'une condition de jointure
derrière WHERE, n'empêche pas l'exécution de la requête, produisant alors un bien
coûteux produit cartésien entre les tables !

Le même exemple que précédemment en utilisant aussi les alias :

SELECT *
FROM Produit A INNER JOIN Détail_Commande B ON A.CodePrd=B.CodePrd ;
Le modèle relationnel 17

La norme SQL2 définit aussi l' équi-jointure naturelle, joignant les 2 tables sur
l'ensemble des attributs qu'elles ont en commun, mais en ne gardant qu'une seule
colonne pour chaque attribut joint, contrairement aux 2 expressions précédentes  :

SELECT *
FROM table1 NATURAL JOIN table2  ;

Il est aussi possible de restreindre (ou préciser) le ou les attributs de jointure avec
USING  :

SELECT *
FROM table1 INNER JOIN table2 USING (attribut1) ;

NATURAL JOIN et USING ne sont pas supportés par tous les SGBDR.

En SQL2, outre la jointure classique (dite jointure interne), apparaissent les  


jointures externes.

On retiendra notamment les jointures externes Gauche (LEFT OUTER JOIN) et


Droite (RIGHT OUTER JOIN).

Dans le cas d'une jointure externe gauche A->B, toute les lignes de la table A sont
incluses même s'il ne leur correspond pas de ligne dans la table B.

Sur l'exemple précédent :

SELECT *
FROM Produit A LEFT OUTER JOIN Détail_Commande B ON
A.CodePrd=B.CodePrd ;

Le résultat renvoyé est le suivant :

A.CodePrd Libellé Prix unitaire N°cde B.CodePrd quantité


590A HD 1,6 Go 1615 97001 590A 2
588J Scanner HP 1700 NULL NULL NULL
515J LBP 660 1820 97002 515J 1
515J LBP 660 1820 97003 515J 3

Tous les produits apparaissent même si certains n'ont pas fait l'objet de commande
(exemple : 588J). Les colonnes manquantes sont alors complétées par des valeurs
NULL.

Exemple :                                                                                      


Le modèle relationnel 18

Libellé
CodePrd Prix unitaire N°cde CodePrd quantité

HD 1,6 Go
590A 1615 97001 590A 2
 
Scanner HP
588J 1700 97002 515J 1

LBP 660
515J 1820 97003 515J 3

 R = JOINTURE (PRODUIT, DETAIL_COMMANDE,


Produit.CodePrd=Détail_Commande.CodePrd)

Libellé
A.CodePrd Prix unitaire N°cde B.CodePrd quantité

HD 1,6 Go
590A 1615 97001 590A 2

LBP 660
515J 1820 97002 515J 1

LBP 660
515J 1820 97003 515J 3

Cet opérateur porte sur 2 relations qui doivent avoir au moins un attribut
défini dans le même domaine (ensemble des valeurs permises pour un
attribut).
La condition de jointure peut porter sur l'égalité d'un ou de plusieurs
attributs définis dans le même domaine (mais n'ayant pas forcément le
même nom).
Les n-uplets de la relation résultat sont formés par la concaténation des n-
uplets des relations d'origine qui vérifient la condition de jointure.

Remarque : Des jointures plus complexes que l'équijointure peuvent être réalisées en
généralisant l'usage de la condition de jointure à d'autres critères de comparaison
que l'égalité (<,>, <=,>=, <>).
Le modèle relationnel 19

Opération UNION

Formalisme : R = UNION (R1, R2)               

Et en langage SQL

SELECT liste d'attributs FROM table1


UNION
SELECT liste d'attributs FROM table 2 ;

Exemple :

SELECT n°enseignant, NomEnseignant FROM E1


UNION
SELECT n°enseignant, NomEnseignant FROM E2 ;

Exemple :
E1 : Enseignants élus au CA                         E2 : Enseignants représentants syndicaux
n° enseignant nom_enseignant n°enseignant nom_enseignant

DUPONT DUPONT
1 1

DURAND   MARTIN
3 4

MARTIN MICHEL
4 6

BERTRAND  
5

On désire obtenir l'ensemble des enseignants élus au CA ou représentants syndicaux.

              R1 = UNION (E1, E2)

nom_enseignant
n°enseignant

DUPONT
1

DURAND
3

MARTIN
4

BERTRAND
5

MICHEL
6
Le modèle relationnel 20

Cet opérateur porte sur deux relations qui doivent avoir le même nombre
d'attributs définis dans le même domaine (ensemble des valeurs permises
pour un attribut). On parle de relations ayant le même schéma.
La relation résultat possède les attributs des relations d'origine et les n-
uplets de chacune, avec élimination des doublons éventuels.

Opération INTERSECTION

Formalisme : R = INTERSECTION (R1, R2)       

Et en langage SQL
En SQL de base, plusieurs possibilités :

SELECT attribut1, attribut2, ... FROM table1


WHERE attribut1 IN (SELECT attribut1 FROM table2) ;

SELECT attribut1, attribut2, ... FROM table1


WHERE EXISTS (SELECT * FROM table2 WHERE table1.attribut1=table2.attribut1)
;

SELECT attribut1, attribut2, ... FROM table1


WHERE attribut1 = ANY (SELECT attribut1 FROM table2) ;

ou avec l'opérateur INTERSECT (SQL2

SELECT attribut1, attribut2, ... FROM table1


INTERSECT
SELECT attribut1, attribut2, ... FROM table2 ;

ou avec une équi-jointure

SELECT attribut1, attribut2, ... FROM table1 INNER JOIN table2 ON


table1.attribut1 = table2.attribut1 ;

Exemple :

SELECT n°enseignant, NomEnseignant FROM E1


        WHERE n°enseignant IN (SELECT n°enseignant FROM E2) ;

ou

SELECT n°enseignant, NomEnseignant FROM E1


INTERSECT
SELECT n°enseignant, NomEnseignant FROM E2 ;
Le modèle relationnel 21

Exemple :

E1 : Enseignants élus au CA                         E2 : Enseignants représentants syndicaux

nom_enseignant nom_enseignant
n° enseignant n°enseignant

DUPONT DUPONT
1 1

DURAND   MARTIN
3 4

MARTIN MICHEL
4 6

BERTRAND  
5

On désire connaître les enseignants du CA qui sont des représentants syndicaux.

              R2 = INTERSECTION (E1, E2)


n°enseignant nom_enseignant

DUPONT
1

MARTIN
4

Cet opérateur porte sur deux relations de même schéma.


La relation résultat possède les attributs des relations d'origine et les n-
uplets communs à chacune.

Opération DIFFERENCE

Formalisme : R = DIFFERENCE (R1, R2)          

Et en langage SQL
Le modèle relationnel 22

En SQL de base, plusieurs possibilités

SELECT attribut1, attribut2, ... FROM table1


WHERE attribut1 NOT IN (SELECT attribut1 FROM table2) ;

SELECT attribut1, attribut2, ... FROM table1


WHERE NOT EXISTS (SELECT * FROM table2 WHERE
table1.attribut1=table2.attribut1) ;

SELECT attribut1, attribut2, ... FROM table1


WHERE attribut1 <> ALL (SELECT attribut1 FROM table2) ;

ou avec l'opérateur EXCEPT (SQL2)

SELECT attribut1, attribut2, ... FROM table1


EXCEPT
SELECT attribut1, attribut2, ... FROM table2 ;

ou encore, avec la jointure externe (SQL2), si par exemple vous utilisez une version
de MySQL qui ne dispose ni du EXCEPT, ni de la possiblité de SELECT imbriqués

SELECT table1.attribut1, table1.attribut2,...


FROM table1 LEFT JOIN table2 ON table1.attribut1 = table2.attribut1
WHERE table2.attribut1 IS NULL ;

Exemple :

SELECT n°enseignant, NomEnseignant FROM E1


        WHERE n°enseignant NOT IN (SELECT n°enseignant FROM E2) ;

ou

SELECT n°enseignant, NomEnseignant FROM E1


EXCEPT
SELECT n°enseignant, NomEnseignant FROM E2 ;

ou encore

SELECT E1.n°enseignant, E1.NomEnseignant


FROM E1 LEFT JOIN E2 ON E1.n°enseignant = E2.n°enseignant
WHERE E2.n°enseignant IS NULL ;

Pour mieux comprendre cette dernière version, voici le résultat renvoyé par la
jointure externe gauche entre E1 et E2 :

E1.n°enseignant E1.NomEnseignant E2.n°enseignant E2.NomEnseignant


Le modèle relationnel 23

1 DUPONT 1 DUPONT
3 DURAND NULL NULL
4 MARTIN 4 MARTIN
5 BERTRAND NULL NULL

Exemple :

E1 : Enseignants élus au CA                  E2 : Enseignants représentants syndicaux

nom_enseignant nom_enseignant
n° enseignant n°enseignant

DUPONT DUPONT
1 1

DURAND MARTIN
3 4

MARTIN MICHEL
4 6

BERTRAND
5

On désire obtenir la liste des enseignants du CA qui ne sont pas des représentants
syndicaux.

R3 = DIFFERENCE (E1, E2)

nom_enseignant
n°enseignant

DURAND
3

BERTRAND
5
 

Cet opérateur porte sur deux relations de même schéma.


La relation résultat possède les attributs des relations d'origine et les n-
uplets de la première relation qui n'appartiennent pas à la deuxième.
Attention ! DIFFERENCE (R1, R2) ne donne pas le même résultat que
Le modèle relationnel 24

DIFFERENCE (R2, R1)

Opération PRODUIT CARTESIEN

Formalisme : R = PRODUIT (R1, R2)       

Et en langage SQL

SELECT * FROM table1, table2 ;

Exemple :

SELECT * FROM Etudiants, Epreuves ;

Exemple :

                             Etudiants                                                  Epreuves

n°étudiant nom libellé épreuve


coefficient

101 DUPONT Informatique


2
 
102 MARTIN Mathématiques
3

  Gestion financière
5

         Examen = PRODUIT (Etudiants, Epreuves)

nom libellé épreuve


n°étudiant coefficient

DUPONT Informatique
101 2

DUPONT Mathématiques
101 3

DUPONT Gestion financière


101 5
Le modèle relationnel 25

MARTIN Informatique
102 2

MARTIN Mathématiques
102 3

MARTIN Gestion financière


102 5

Cet opérateur porte sur deux relations.


La relation résultat possède les attributs de chacune des relations d'origine et
ses n-uplets sont formés par la concaténation de chaque n-uplet de la
première relation avec l'ensemble des n-uplets de la deuxième.

Principe d'écriture d'une requête       

La plupart des requêtes (ou interrogations) portant sur une base de données
relationnelle ne peuvent pas être réalisées à partir d'une seule opération mais en
enchaînant successivement plusieurs opérations.

Exemple

Soient les deux tables (ou relations) suivantes :

CLIENT(CodeClient, NomClient, AdrClient, TélClient)


COMMANDE(N°Commande, Date, CodeClient*)

Remarque : les clés primaires sont soulignées et les clés étrangères sont marquées
par *

On désire obtenir le code et le nom des clients ayant commandé le 10/06/97 :

R1=SELECTION(COMMANDE, Date=10/06/97)
R2=JOINTURE(R1, CLIENT, R1.CodeClient=CLIENT.CodeClient)
R3=PROJECTION(R2, CodeClient, NomClient)

Exercice d'application n°1

Soit le modèle relationnel suivant relatif à une base de données sur des
représentations musicales :

REPRESENTATION (n°représentation, titre_représentation, lieu)


MUSICIEN (nom, n°représentation*)
PROGRAMMER (date, n°représentation*, tarif)
Le modèle relationnel 26

Remarque : les clés primaires sont soulignées et les clés étrangères sont marquées par
*

Questions :

1 - Donner la liste des titres des représentations.

2 - Donner la liste des titres des représentations ayant lieu à l'opéra Bastille.

3 - Donner la liste des noms des musiciens et des titres des représentations
auxquelles ils participent.

4 - Donner la liste des titres des représentations, les lieux et les tarifs pour la journée
du 14/09/96.

Correction de l'exercice d'application n°1  

REPRESENTATION (n°représentation, titre_représentation, lieu)


MUSICIEN (nom, n°représentation*)
PROGRAMMER (date, n°représentation*, tarif)

1 - Donner la liste des titres des représentations.


R = PROJECTION(REPRESENTATION, titre_représentation)

Et en langage SQL...

SELECT titre_représentation FROM REPRESENTATION ;

2 - Donner la liste des titres des représentations ayant lieu à l'opéra Bastille.
R1 = SELECTION(REPRESENTATION, lieu="Opéra Bastille")
R2 = PROJECTION(R1, titre_représentation)

Et en langage SQL...

SELECT titre_représentation FROM REPRESENTATION


WHERE lieu="Opéra Bastille" ;

3 - Donner la liste des noms des musiciens et des titres des représentations
auxquelles ils participent.
R1 = JOINTURE(MUSICIEN, REPRESENTATION,
Musicien.n°représentation=Représentation.n°représentation)
R2 = PROJECTION(R1, nom, titre_représentation)

Et en langage SQL...
Le modèle relationnel 27

SELECT nom, titre_représentation


FROM MUSICIEN INNER JOIN REPRESENTATION
ON MUSICIEN.n°représentation = REPRESENTATION.n°représentation ;

4 - Donner la liste des titres des représentations, les lieux et les tarifs pour la
journée du 14/09/96.
R1 = SELECTION(PROGRAMMER, date=14/09/96)
R2 = JOINTURE(R1, REPRESENTATION,
R1.n°représentation=Représentation.n°représentation)
R3 = PROJECTION(R2, titre_représentation, lieu, tarif)

Et en langage SQL...

SELECT titre_représentation, lieu, tarif


FROM REPRESENTATION INNER JOIN PROGRAMMER
ON PROGRAMMER.n°représentation =
REPRESENTATION.n°représentation
WHERE date='14/06/96' ;

Opération CALCULER    

R=CALCULER(R0, fonction1, fonction2, ...)     ou     N=CALCULER(R0, fonction)

Et en langage SQL

SELECT fonction_agreg1(attribut1), fonction_agreg2(attribut2), ...


FROM table ;

Exemple :

SELECT SUM(Quantité*PuHt), SUM(Quantité)


        FROM LIGNE_COMMANDE;

Exemple

LIGNE_COMMANDE

N°BonCommande CodeProduit Quantité PuHt


Le modèle relationnel 28

96008 A10 10 83
96008 B20 35 32
96009 A10 20 83
96010 A15 4 110
96010 B20 55 32

On désire obtenir le chiffre d'affaires total Ht, ainsi que le nombre total de produits
commandés :
R1=CALCULER(LIGNE_COMMANDE, Somme(Quantité*PuHt), Somme(Quantité))

Somme(Quantité*PuHt) Somme(Quantité)
5810 124
 
Les calculs et/ou comptage portent sur la relation R0.
La relation résultat ne comportera qu'une ligne avec autant de colonnes que
de résultats demandés ou pourra simplement être considérée comme un
nombre N utilisable ultérieurement en tant que tel dans le cas où un seul
résultat est attendu.

 Opération REGROUPER_ET_CALCULER

R=REGROUPER_ET_CALCULER(R0, att1, att2, ..., fonction1, fonction2, ...)

Et en langage SQL

SELECT attribut1, attribut2, ..., fonction_agreg1(attribut3),


fonction_agreg2(attribut4), ...
FROM table
GROUP BY attribut1, attribut2, ... ;

Exemple :

SELECT N°BonCommande, SUM(Quantité*PuHt)


        FROM LIGNE_COMMANDE
        GROUP BY N°BonCommande ;

La clause GROUP BY est obligatoire dès qu'il y a à la fois des attributs et des
fonctions d'agrégation derrière la clause SELECT.
Sur la plupart des SGBDR, tous les attributs placés derrière la clause SELECT
doivent être présents derrière la clause GROUP BY. La proposition inverse n'est
pas vraie.
Le modèle relationnel 29

Il est possible de sélectionner des lignes issues d'un regroupement (grâce à la clause
HAVING) et même de les trier.

Exemple : on souhaite, parmi l'ensemble des commandes, ne retenir que celles dont
le montant total hors taxes est supérieur à 10000. De plus on souhaite les voir
apparaître par ordre décroissant de leurs montants respectifs.

SELECT N°BonCommande, SUM(Quantité*PuHt)


        FROM LIGNE_COMMANDE
        GROUP BY N°BonCommande HAVING SUM(Quantité*PuHt)>10000
        ORDER BY 2 DESC ;

Il n'est pas toujours possible de placer une fonction derrière la clause ORDER BY.
Mais les colonnes projetées derrière la clause SELECT étant implicitement
numérotées de 1 à n, il est facile d'y faire référence. Ceci explique la présence du
chiffre 2 derrière le ORDER BY de l'exemple : il fait référence à
SUM(Quantité*PuHt).

Exemple

LIGNE_COMMANDE

N°BonCommande CodeProduit Quantité PuHt


96008 A10 10 83
96008 B20 35 32
96009 A10 20 83
96010 A15 4 110
96010 B20 55 32

On désire obtenir le montant total Ht de chaque bon de commande :


R2=REGROUPER_ET_CALCULER(LIGNE_COMMANDE, N°BonCommande,
MontantHt : Somme(Quantité*PuHt))

N°BonCommande MontantHt
96008 1950
96009 1660
Le modèle relationnel 30

96010 2200

Le regroupement s'effectue sur un sous ensemble des attributs de la relation


R0.
La relation résultat comportera autant de lignes que de groupes de n-uplets,
les fonctions s'appliquant à chacun des groupes séparément.

Les Fonctions d'agrégation      

Elles sont utilisées dans les opérateurs CALCULER et


REGROUPER_ET_CALCULER.

Et en langage SQL

Elles sont utilisées avec les opérateurs de calcul et de regroupement.

Les fonctions statistiques de base

SUM(attribut) : total des valeurs d'un attribut


AVG(attribut) : moyenne des valeurs d'un attribut
MIN(attribut) : plus petite valeur d'un attribut
MAX(attribut) : plus grande valeur d'un attribut

Remarque : les valeurs NULL sont ignorées.

La fonction de comptage

COUNT(*) : nombre de n-uplets

COUNT(DISTINCT attribut) : nombre de valeurs différentes de l'attribut

Les fonctions statistiques de base

Elles portent sur un ou plusieurs groupes de n-uplets et évidemment sur un attribut


de type numérique.

Somme(attribut) : total des valeurs d'un attribut


Moyenne(attribut) : moyenne des valeurs d'un attribut
Minimum(attribut) : plus petite valeur d'un attribut
Maximum(attribut) : plus grande valeur d'un attribut

Remarque : les valeurs "non renseignées" de l'attribut sont ignorées.


Le modèle relationnel 31

La fonction de comptage : Comptage()

La fonction de comptage donne le nombre de n-uplets d'un ou de plusieurs groupes de n-


uplets. Il n'est donc pas nécessaire de préciser d'attribut.

Opération TRI   

R = TRI(R0, att1↑, att2↓, ...)

Et en langage SQL

SELECT attribut1, attribut2, attribut3, ...


FROM table
ORDER BY attribut1 ASC, attribut2 DESC, ... ;

ASC : par ordre croissant (Ascending)


DESC : par ordre décroissant (Descending)

Exemple :

SELECT Espèce, Catégorie, Conditionnement


FROM Champignons
ORDER BY Espèce DESC, Catégorie ASC, Conditionnement ASC ;

Remarque : par défaut le tri se fait par ordre croissant si l'on ne précise pas ASC ou
DESC.
Exemple :
                           CHAMPIGNONS
Espèce Catégorie Conditionnement
Rosé des prés Conserve Bocal
Rosé des prés Sec Verrine
Coulemelle Frais Boîte
Rosé des prés Sec Sachet plastique

R1 = TRI (CHAMPIGNONS, Espèce↓,Catégorie↑,Conditionnement↑)

Espèce Catégorie Conditionnement


Rosé des prés Conserve Bocal
Le modèle relationnel 32

Rosé des prés Sec Sachet plastique


Rosé des prés Sec Verrine
Coulemelle Frais Boîte

Le tri s'effectue sur un ou plusieurs attributs, dans l'ordre croissant ou


décroissant.
La relation résultat a la même structure et le même contenu que la relation
de départ.

 Attributs calculés et renommés  


Attributs calculés

Un attribut calculé est un attribut dont les valeurs sont obtenues par des opérations
arithmétiques portant sur des attributs de la même relation.
Le calcul est spécifié lors d'une projection ou lors de l'utilisation d'une fonction.

R=PROJECTION(R0, att1, att2, att3, att4, att1*att2, att3/att2)

 
Attributs renommés

Il est possible de renommer n'importe quel attribut en le faisant précéder de son


nouveau nom suivi de ":".

R=PROJECTION(R0, att1, att2, att3, att4, newatt1:att1*att2, newatt2:att3/att2)

Et en langage SQL

Attributs calculés

SELECT N°BonCommande, CodeProduit, Quantité*PuHt


FROM LIGNE_COMMANDE ;

 
Attributs renommés

SELECT N°BonCommande, CodeProduit, Quantité*PuHt AS Montant


FROM LIGNE_COMMANDE ;

Exemple

LIGNE_COMMANDE
Le modèle relationnel 33

N°BonCommande CodeProduit Quantité PuHt


96008 A10 10 83
96008 B20 35 32
96009 A10 20 83
96010 A15 4 110
96010 B20 55 32

R=PROJECTION(LIGNE_COMMANDE, N°BonCommande, CodeProduit,


Montant:Quantité*PuHt)

N°BonCommande CodeProduit Montant


96008 A10 830
96008 B20 1120
96009 A10 1660
96010 A15 440
96010 B20 1760

Exercice d'application n°2

Soit le modèle relationnel suivant relatif à la gestion des notes annuelles d'une
promotion d'étudiants :

ETUDIANT(N°Etudiant, Nom, Prénom)


MATIERE(CodeMat, LibelléMat, CoeffMat)
EVALUER(N°Etudiant*, CodeMat*, Date, Note)

Remarque : les clés primaires sont soulignées et les clés étrangères sont marquées par
*

Questions :

1 - Quel est le nombre total d'étudiants ?

2 - Quelles sont, parmi l'ensemble des notes, la note la plus haute et la note la plus
basse ?

3 - Quelles sont les moyennes de chaque étudiant dans chacune des matières ?

4 - Quelles sont les moyennes par matière ?

5 - Quelle est la moyenne générale de chaque étudiant ?

6 - Quelle est la moyenne générale de la promotion ?


Le modèle relationnel 34

7 - Quels sont les étudiants qui ont une moyenne générale supérieure ou égale à la
moyenne générale de la promotion ?

Correction de l'exercice d'application n°2  

ETUDIANT(N°Etudiant, Nom, Prénom)


MATIERE(CodeMat, LibelléMat, CoeffMat)
EVALUER(N°Etudiant*, CodeMat*, Date, Note)

1 - Quel est le nombre total d'étudiants ?


N=CALCULER(ETUDIANT, Comptage())

Et en langage SQL...

SELECT COUNT(*) FROM ETUDIANT ;

2 - Quelles sont, parmi l'ensemble des notes, la note la plus haute et la note la plus
basse ?
R=CALCULER(EVALUER, Minimum(Note), Maximum(Note))
Et en langage SQL...

SELECT MIN(Note), MAX(Note) FROM EVALUER ;

3 - Quelles sont les moyennes de chaque étudiant dans chacune des matières ?
R1=REGROUPER_ET_CALCULER(EVALUER, N°Etudiant, CodeMat, MoyEtuMat :
Moyenne(Note))
R2=JOINTURE(R1, MATIERE, MATIERE.CodeMat=R1.CodeMat)
R3=JOINTURE(R2, ETUDIANT, ETUDIANT.N°Etudiant=R2.N°Etudiant)
MOYETUMAT=PROJECTION(R3, N°Etudiant, Nom, Prénom, LibelléMat, CoeffMat,
MoyEtuMat)

Et en langage SQL...

CREATE VIEW MOYETUMAT AS


SELECT ETUDIANT.N°Etudiant, Nom, Prénom, LibelléMat, CoeffMat,
AVG(Note) AS MoyEtuMat
FROM EVALUER INNER JOIN MATIERE ON EVALUER.CodeMat =
MATIERE.CodeMat
INNER JOIN ETUDIANT ON EVALUER.N°Etudiant =
ETUDIANT.N°Etudiant
GROUP BY ETUDIANT.N°Etudiant, Nom, Prénom, LibelléMat, CoeffMat;

Remarque : la commande CREATE VIEW va permettre de réutiliser le résultat


de la requête (notamment aux deux questions suivantes) comme s'il s'agissait
d'une nouvelle table (bien qu'elle soit regénérée dynamiquement lors de son
Le modèle relationnel 35

utilisation).
Sous Access, il ne faut pas utiliser la commande CREATE VIEW mais
seulement enregistrer la requête. Il est alors possible de s'en resservir comme
une table.

4 - Quelles sont les moyennes par matière ?


Idem question 3 puis :
R4=REGROUPER_ET_CALCULER(MOYETUMAT, LibelléMat,
Moyenne(MoyEtuMat))
Et en langage SQL...

Avec la vue MOYETUMAT de la question 3 :


SELECT LibelléMat, AVG(MoyEtuMat)
FROM MOYETUMAT
GROUP BY LibelléMat ;

5 - Quelle est la moyenne générale de chaque étudiant ?


Idem question 3 puis
MGETU=REGROUPER_ET_CALCULER(MOYETUMAT, N°Etudiant, Nom,
Prénom, MgEtu : Somme(MoyEtuMat*CoeffMat)/Somme(CoeffMat))
Et en langage SQL...
Avec la vue MOYETUMAT de la question 3 :
CREATE VIEW MGETU AS
SELECT N°Etudiant, Nom, Prénom,
SUM(MoyEtuMat*CoeffMat)/SUM(CoeffMat) AS MgEtu
FROM MOYETUMAT
GROUP BY N°Etudiant, Nom, Prénom ;

6 - Quelle est la moyenne générale de la promotion ?


Idem question 5 puis
MG=CALCULER(MGETU, Moyenne(MgEtu))

Et en langage SQL...

Avec la vue MGETU de la question 5 :


SELECT AVG(MgEtu)
FROM MGETU ;

7 - Quels sont les étudiants qui ont une moyenne générale supérieure ou égale à la
moyenne générale de la promotion ?
idem question 5 et 6 puis :
R=SELECTION(MGETU, MgEtu>=MG)

Et en langage SQL...
Le modèle relationnel 36

Avec la vue MGETU de la question 5 :


SELECT N°Etudiant, Nom, Prénom, MgEtu
FROM MGETU
WHERE MgEtu >= (SELECT AVG(MgEtu) FROM MGETU) ;

Opération DIVISION

Formalisme : R = DIVISION (R1, R2)                

Et en langage SQL

Il n'existe pas en SQL d'équivalent direct à la division.

Cependant il est toujours possible de trouver une autre solution, notamment par
l'intermédiaire des opérations de calcul et de regroupement.

Dans l'exemple présenté, on souhaite trouver les athlètes qui participent à toutes les
épreuves. En algèbre relationnelle une autre solution que la division pourrait être :

N=CALCULER(EPREUVE, Comptage())
R1=REGROUPER_ET_CALCULER(PARTICIPER, Athlète, Nb:Comptage())
R2=SELECTION(R1, Nb=N)
R3=PROJECTION(R2, Athlète)

et en SQL :

SELECT Athlète FROM PARTICIPER


GROUP BY Athlète
HAVING COUNT(*) = (SELECT COUNT(*) FROM EPREUVE) ;

On pourra trouver cette solution imparfaite par rapport aux solutions plus "propres"
généralement données pour la division, solutions souvent basées sur une double
négation et mettant en oeuvre plusieurs SELECT imbriqués et corrélés (très coûteux
en temps d'exécution). Approfondissons les choses avec un autre jeu d'essai
volontairement plus contraignant :

PARTICIPER EPREUVE
Athlète Epreuve Epreuve
Dupont 200 m 200 m
Dupont 400 m 400 m
Dupont 110 m H 110 m H
Dupont 100 m 200 m
Martin 200 m
Martin 400 m
Martin 110 m H
Bertrand 200 m
Le modèle relationnel 37

Bertrand 400 m
Michel 200 m
On peut alors vouloir obtenir :
1) les athlètes ayant participé au moins à toutes les épreuves de la table EPREUVE
(Dupont et Martin)
2) les athlètes qui ont participé uniquement aux épreuves de la table EPREUVE et à
aucune autre (Division "exacte"), ici Martin.
Dans le 1er cas, la solution n'est guère plus compliquée :

SELECT Athlète FROM PARTICIPER


WHERE Epreuve IN (SELECT Epreuve FROM EPREUVE)
GROUP BY Athlète
HAVING COUNT(*) = (SELECT COUNT(DISTINCT Epreuve) FROM
EPREUVE) ;

Dans le 2ème cas, il est encore possible de répondre assez "simplement" à la question
sur la base d'une jointure externe (SQL2) et en utilisant la particularité des fonctions
d'agrégation d'ignorer les valeurs nulles. Voici cette solution :

SELECT Athlète
FROM PARTICIPER A LEFT JOIN (SELECT DISTINCT Epreuve FROM
EPREUVE) B ON A.Epreuve = B.Epreuve
GROUP BY Athlète
HAVING COUNT(*) = (SELECT COUNT(DISTINCT Epreuve) FROM EPREUVE)
AND COUNT(B.Epreuve) = (SELECT COUNT(DISTINCT Epreuve) FROM
EPREUVE) ;

Pour mieux comprendre, voici le résultat renvoyé par la jointure externe


gauche (LEFT JOIN) entre PARTICIPER et EPREUVE :

Athlète A.Epreuve B.Epreuve


Dupont 200 m 200 m
Dupont 400 m 400 m
Dupont 110 m H 110 m H
Dupont 100 m NULL
Martin 200 m 200 m
Martin 400 m 400 m
Martin 110 m H 110 m H
Bertrand 400 m 400 m
Bertrand 200 m 200 m
Michel 200 m 200 m
Ensuite le regroupement avec comptage renvoie :
Athlète COUNT(*) COUNT(B.Epreuve)
Dupont 4 3
Le modèle relationnel 38

Martin 3 3
Bertrand 2 2
Michel 1 1
Seul Martin a les 2 résultats égaux au nombre d'épreuves différentes (et vérifie donc
la condition exprimée derrière le HAVING). CQFD !
Je vous laisse comparer avec l'autre type de solution (plus élégante) basée sur la
double négation et les SELECT imbriqués et corrélés :
SELECT Athlète FROM PARTICIPER A
WHERE NOT EXISTS (SELECT * FROM EPREUVE
                                            WHERE NOT EXISTS (SELECT * FROM PARTICIPER B
                                                                                        WHERE (A.Athlète = B.Athlète)
                                                                                             AND (B.Epreuve =
EPREUVE.Epreuve)))
GROUP BY Athlète
HAVING COUNT(*) = (SELECT COUNT (DISTINCT Epreuve) FROM EPREUVE)
;

Exemple :

      PARTICIPER                EPREUVE       DIVISION (PARTICIPER, EPREUVE)


Athlète Epreuve Epreuve Athlète
Dupont 200 m 200 m Dupont
Durand 400 m 400 m
Dupont 400 m 110 m H
Martin 110 m H
Dupont 110 m H
Martin 200 m

            "L'athlète Dupont participe à toutes les épreuves"

Cet opérateur porte sur 2 relations qui doivent avoir au moins un attribut
défini dans le même domaine.
Tous les attributs du diviseur (ici EPREUVE) doivent être des attributs du
dividende (ici PARTICIPER).
La relation dividende doit avoir au moins une colonne de plus que la
relation diviseur.
La relation résultat, le quotient, possède les attributs non communs aux deux
relations initiales et est formée de tous les n-uplets qui, concaténés à chacun
des n-uplets du diviseur (ici EPREUVE) donne toujours un n-uplet du
dividende (ici PARTICIPER).
Le modèle relationnel 39

Exercice d'application n°3

Soit le modèle relationnel suivant relatif à la gestion simplifiée des étapes du Tour de
France 97, dont une des étapes de type "contre la montre individuel" se déroula à
Saint-Etienne :

EQUIPE(CodeEquipe, NomEquipe, DirecteurSportif)


COUREUR(NuméroCoureur, NomCoureur, CodeEquipe*, CodePays*)
PAYS(CodePays, NomPays)
TYPE_ETAPE(CodeType, LibelléType)
ETAPE(NuméroEtape, DateEtape, VilleDép, VilleArr, NbKm, CodeType*)
PARTICIPER(NuméroCoureur*, NuméroEtape*, TempsRéalisé)
ATTRIBUER_BONIFICATION(NuméroEtape*, km, Rang, NbSecondes,
NuméroCoureur*)

Remarque : les clés primaires sont soulignées et les clés étrangères sont marquées par
*

Questions :

1 - Quelle est la composition de l'équipe Festina (Numéro, nom et pays des


coureurs) ?

2 - Quel est le nombre de kilomètres total du Tour de France 97 ?

3 - Quel est le nombre de kilomètres total des étapes de type "Haute Montagne" ?

4 - Quels sont les noms des coureurs qui n'ont pas obtenu de bonifications ?

5 - Quels sont les noms des coureurs qui ont participé à toutes les étapes ?

6 - Quel est le classement général des coureurs (nom, code équipe, code pays et
temps des coureurs) à l'issue des 13 premières étapes sachant que les bonifications
ont été intégrées dans les temps réalisés à chaque étape ?

Correction de l'exercice d'application n°3  

EQUIPE(CodeEquipe, NomEquipe, DirecteurSportif)


COUREUR(NuméroCoureur, NomCoureur, CodeEquipe*, CodePays*)
PAYS(CodePays, NomPays)
TYPE_ETAPE(CodeType, LibelléType)
ETAPE(NuméroEtape, DateEtape, VilleDép, VilleArr, NbKm, CodeType*)
PARTICIPER(NuméroCoureur*, NuméroEtape*, TempsRéalisé)
ATTRIBUER_BONIFICATION(NuméroEtape*, km, Rang, NbSecondes,
NuméroCoureur*)

1 - Quelle est la composition de l'équipe FESTINA (Numéro, nom et pays des


coureurs) ?
Le modèle relationnel 40

R1=SELECTION(EQUIPE, NomEquipe="FESTINA")
R2=JOINTURE(R1, COUREUR, R1.CodeEquipe=COUREUR.CodeEquipe)
R3=JOINTURE(R2, PAYS, R2.CodePays=PAYS.CodePays)
R4=PROJECTION(R3, NuméroCoureur, NomCoureur, NomPays)

Et en langage SQL...

SELECT NuméroCoureur, NomCoureur, NomPays


FROM EQUIPE A INNER JOIN COUREUR B ON
A.CodeEquipe=B.CodeEquipe
INNER JOIN PAYS C ON B.CodePays=C.CodePays
WHERE NomEquipe="FESTINA" ;
2 - Quel est le nombre de kilomètres total du Tour de France 97 ?
N=CALCULER(ETAPE, SOMME(NbKm))
Et en langage SQL...

SELECT SUM(Nbkm) FROM ETAPE ;

3 - Quel est le nombre de kilomètres total des étapes de type HAUTE


MONTAGNE ?
R1=SELECTION(TYPE_ETAPE, LibelléType="HAUTE MONTAGNE")
R2=JOINTURE(R1, ETAPE, R1.CodeType=ETAPE.CodeType)
N=CALCULER(R2, SOMME(NbKm))
Et en langage SQL...

SELECT SUM(Nbkm)
FROM ETAPE A INNER JOIN TYPE_ETAPE B ON
A.CodeType=B.CodeType
WHERE LibelléType="HAUTE MONTAGNE" ;

4 - Quels sont les noms des coureurs qui n'ont pas obtenu de bonifications ?
R1=PROJECTION(COUREUR, NuméroCoureur)
R2=PROJECTION(ATTRIBUER_BONIFICATION, NuméroCoureur)
R3=DIFFERENCE(R1,R2)
R4=JOINTURE(R3, COUREUR, R3.NuméroCoureur=COUREUR.NuméroCoureur)
R5=PROJECTION(R4, NomCoureur)

Et en langage SQL...

SELECT NomCoureur FROM COUREUR


WHERE NuméroCoureur NOT IN (SELECT NuméroCoureur FROM
ATTRIBUER_BONIFICATION) ;
ou
SELECT NomCoureur
FROM COUREUR C LEFT JOIN ATTRIBUER_BONIFICATION A ON
Le modèle relationnel 41

C.NuméroCoureur=A.NuméroCoureur
WHERE A.NuméroCoureur IS NULL ;  

5 - Quels sont les noms des coureurs qui ont participé à toutes les étapes ?
R1=PROJECTION(PARTICIPER, NuméroCoureur, NuméroEtape)
R2=PROJECTION(ETAPE, NuméroEtape)
R3=DIVISION(R1, R2)
R4=JOINTURE(R3, COUREUR, R3.NuméroCoureur=COUREUR.NuméroCoureur)
R5=PROJECTION(R4, NomCoureur)

ou

N=CALCULER(ETAPE, Comptage())
R1=REGROUPER_ET_CALCULER(PARTICIPER, NuméroCoureur, Nb:Comptage())
R2=SELECTION(R1, Nb=N)
R3=JOINTURE(R2, COUREUR, R2.NuméroCoureur=COUREUR.NuméroCoureur)
R4=PROJECTION(R3, NomCoureur)

Et en langage SQL...

SELECT NomCoureur
FROM PARTICIPER A INNER JOIN COUREUR B ON
A.NuméroCoureur=B.NuméroCoureur
GROUP BY NuméroCoureur, NomCoureur
HAVING COUNT(*)=(SELECT COUNT(*) FROM ETAPE) ;

6 - Quel est le classement général des coureurs (nom, code équipe, code pays et
temps des coureurs) à l'issue des 13 premières étapes sachant que les bonifications
ont été intégrées dans les temps réalisés à chaque étape ?
R1=SELECTION(PARTICIPER, NuméroEtape=13)
R2=PROJECTION(R1, NuméroCoureur)
-> R2 représente l'ensemble des coureurs présents jusqu'à la 13ème étape (ce qui va
permettre de ne pas prendre en compte dans le classement ceux qui ont abandonné
avant !)
R3=JOINTURE(R2, PARTICIPER,
R2.NuméroCoureur=PARTICIPER.NuméroCoureur)
R4=SELECTION(R3, NuméroEtape<=13)
R5=REGROUPER_ET_CALCULER(R4, NuméroCoureur,
Total:Somme(TempsRéalisé))
R6=JOINTURE(R5, COUREUR, R5.NuméroCoureur=COUREUR.NuméroCoureur)
R7=PROJECTION(R6, NomCoureur, CodeEquipe, CodePays, Total)
R8=TRI(R7, Total)

Et en langage SQL...
Le modèle relationnel 42

SELECT NomCoureur, CodeEquipe, CodePays, SUM(TempsRéalisé) AS


Total
FROM PARTICIPER A INNER JOIN COUREUR B ON
A.NuméroCoureur=B.NuméroCoureur 
WHERE NuméroEtape<=13 AND A.NuméroCoureur IN
 (SELECT NuméroCoureur FROM PARTICIPER WHERE NuméroEtape=13) 
GROUP BY A.NuméroCoureur, NomCoureur, CodeEquipe, CodePays
ORDER BY 4 ;

Vous aimerez peut-être aussi