Chapitre 9: Requêtes dans les bases de données 1 Introduction : limite des structures de données plates pour la recherche d informations On souhaite représenter l ensemble des élèves de première année des classes préparatoires du lycée Masséna, sachant qu ils sont regroupés par classes. Les élèves ont certains attributs : leur nom ; leur lycée d origine en terminale ; la filière (MPSI ou PCSI) suivie ; le numéro (1 ou 2). Prenons pour simplifier un ensemble d élèves réduit : Prénom Nom Filière Numéro Lycée d origine Mathilde Dufour PCSI 2 Calmette Léa Dupond MPSI 2 Massena Paul Dugommier PCSI 1 Massena Mathilde Dugommier MPSI 1 Calmette Clément Durand PCSI 1 Parc Imperial On peut, en Python, choisir plusieurs représentations de ces données. On pourrait grouper les élèves par classe, puis par filière : classes_de_sup=[ [ [['Mathilde', 'Dugommier', 'Calmette']], [['Léa', 'Dupond', 'Massena']] ], [ [['Paul', 'Dugommier', 'Massena'], ['Clément', 'Durand', 'Parc Imperial']], [['Mathilde', 'Dufour', 'Calmette']] ] ] Ici, classes_de_sup[1] fournit par exemple les deux classes de PCSI, alors que classes_de_sup[0][0] donne la liste des élèves de MPSI 1. Dans les deux cas le lycée d origine est présent. Si on veut extraire simplement la liste des élèves d une classe (sans le lycée d origine), on ferait quelque chose comme >>> print([x[:2] for x in classes_de_sup[1][0]]) [['Paul', 'Dugommier'], ['Clément', 'Durand']] Par contre, si on veut la liste des élèves venant du lycée Calmette, il faut un peu plus travailler : lycee_calmette=[] for filiere in classes_de_sup: for classe in filiere: for eleve in classe: if eleve[2]=='calmette': lycee_calmette.append(eleve[:2]) On obtient bien : Svartz Page 1/15 2014/2015
>>> print lycee_calmette [['Mathilde', 'Dugommier'], ['Mathilde', 'Dufour']] On pourrait aussi regrouper les élèves par lycée d origine, par contre la liste des élèves de MPSI 1 (par exemple) serait plus dure à établir. Il est aussi possible de stocker des 5-uplets comme dans le tableau ci-dessus, au prix par contre d un stockage important de données (il faut imaginer qu il y a beaucoup plus d élèves...) 2 Présentation succincte des bases de données Le rôle des bases de données est de simplifier le genre de considérations de la section précédente, en permettant : d avoir une structure de données efficace ; une rapidité d accès ; d éviter à l utilisateur d avoir à s interroger sur la manière dont sont stockées les données ; une sauvegarde des modifications ; une gestion des pannes ; une gestion des conflits si plusieurs utilisateurs modifient la base en même temps ;... Par exemple, pour les élèves des différentes classes, on pourrait imaginer un système avec trois tables du type : Table Eleves prénom nom classe id_lycee Mathilde Dufour 834 1 Léa Dupond 832 2 Paul Dugommier 833 2 Mathilde Dugommier 831 1 Clément Durand 833 3 Table Lycees id_lycee lycee 1 Calmette 2 Massena 3 Parc Imperial Table Classes classe filière numéro 831 MPSI 1 832 MPSI 2 833 PCSI 1 834 PCSI 2 La table des lycées ne possède que deux attributs (colonnes), mais on pourrait imaginer vouloir rajouter d autres attributs (ville, nombre de classes de terminale...), on n aurait pas à modifier toute la base. On remarque que notre découpage d informations permet de limiter la redondance : on n indique pour chaque élève que son numéro de classe, et pas sa filière et son numéro, informations qu on peut retrouver facilement à partir du numéro de classe. Voici des exemples de requêtes qu on peut réaliser sur ces tables : sélectionner les élèves de MPSI 1, et les classer par ordre alphabétique SELECT nom,prenom FROM Eleves WHERE classe=831 ORDER BY nom Ici, on a supposé que l on connaissait le code de la MPSI 1, si ce n est pas le cas, il faut croiser les tables : sélectionner les élèves de MPSI 1, et les classer par ordre alphabétique, version 2 SELECT nom, prenom FROM eleves JOIN classes ON eleves.classe=classes.classe WHERE filiere="mpsi" AND numero=1 ORDER BY nom ; De même, pour sélectionner les élèves venant de Calmette : SELECT nom, prenom FROM Eleves JOIN Lycees ON Eleves.id_lycee=Lycees.id_lycee WHERE lyceenom="calmette" ; Pour connaître le nombre d élèves en MPSI : SELECT COUNT (*) FROM Eleves JOIN Classes ON Eleves.classe=Classes.classe WHERE Filiere="MPSI" ; Svartz Page 2/15 2014/2015
Depuis 1970 deux modèles abstraits de structure des données et d extraction ont été étudiés : l algèbre relationnelle et le calcul relationnel. Ils sont prouvés équivalents et ont servi de base théorique aux logiciels de base de données que les progrès de l informatique ont permis d écrire de manière efficace. Le modèle que l on va étudier dans ce cours est l algèbre relationnelle. Les bases de données sont articulées sous la forme client-serveur : l utilisateur travaille sur un poste (client) qui peut être éloigné de l ordinateur qui gère les données (serveur). Il est nécessaire de permettre un dialogue entre ces deux parties. Client SQL Serveur Une normalisation (rare en informatique) a permis d unifier le langage utilisé dans les bases de données : SQL. Du point de vue des utilisateurs, la syntaxe est la même, en tout cas pour les fonctionnalités de base. Par contre, la programmation en interne de ces logiciels dépend de l éditeur (Oracle, SAP, IBM, Microsoft,...), mais cela nous préoccupera assez peu. Dans ce cours, nous allons étudier les principales fonctions en commençant par les bases simples (ou plates) puis en étudiant ce qui fait l intérêt des bases, le croisement de données. Essentiellement ici, on va voir comment interroger une base de données, sans en créer ni en modifier (ce qui sera vu plus tard). En général, le langage SQL n est en fait pas visible pour les usagers. En effet l utilisation des bases de données se fait usuellement à travers une architecture «trois-tiers». Entre l usager et la base de données se trouve un serveur applicatif qui traduit les demandes de l utilisateur (en général via une interface graphique) au gestionnaire de bases de données. Client Client Interface Application SQL Serveur Client Par exemple, lorsque l on se connecte à Pronote, tout le côté «bases de données» est invisible pour l utilisateur, seule l application Pronote est disponible. C est elle qui gère les droits d accès : un élève ne peut consulter les notes d un autre, tandis qu un professeur de mathématiques ne peut rentrer des notes de physique chimie... 3 Structure 3.1 Tableau Le modèle utilisé est relativement simple : c est celui d un tableau à deux dimensions que nous avons tous souvent rencontré. On regroupe plusieurs formulaires qui donnent tous les mêmes informations sur les objets : répertoire (nom, téléphone, adresse,...) fiche de bibliothèque (auteur, titre, année, pagination,...) livre d état-civil des naissances (père, mère, nom, lieu,...)... Et on les représente dans un tableau, par exemple dans un tableur. Nous ferons le choix que les données des différents éléments sont en ligne et que les informations sont alignées par colonne. Voici un exemple simple dont nous nous servirons. Svartz Page 3/15 2014/2015
3.2 Vocabulaire Table eleve prenom nom filiere numero lycee_origine note_bac Mathilde Dufour PCSI 2 Calmette 18 Léa Dupond MPSI 2 Massena 14 Paul Dugommier PCSI 1 Massena 12 Mathilde Dugommier MPSI 1 Calmette 15 Clément Durand PCSI 1 Parc Imperial 13 Attributs. Les différents titres de colonnes sont appelés attributs. On notera formellement A 1, A 2,, A p les attributs. Les attributs forment un ensemble : il n y a pas d attribut en double. L ordre des attributs n est pas fixé : on ne parle pas du premier attribut mais de l attribut nom (par exemple). La table précédente présente 6 attributs. Domaine. L ensemble des valeurs que peut prendre un attribut A est son domaine Dom(A). Par exemple, pour la table ci-dessus, quatre attributs peuvent avoir pour domaine des chaînes de caractères, mais on peut imaginer que le domaine des classes est réduit à l ensemble des sigles dénotant une filière de classe préparatoire (MPSI,PCSI, BCPST, PSI...), le numéro est un entier, et la note du bac un flottant (qu on peut imposer dans l intervalle [0, 20] avec éventuellement un certain nombre de chiffres significatifs...). Tout cela a été fixé à la création de la base, et ne va donc pas nous concerner pour le moment. Schéma relationnel. On appelle schéma relationnel un p-uplet d attributs, vérifiant toujours la contrainte que les attributs sont distincts deux à deux. On notera S dans ce cours un schéma relationnel. Tuple. Chaque ligne s appelle un p-uplet (ou tuple en anglais). C est donc un élément de Dom(A 1 ) Dom(A 2 ) Dom(A p ). En fait, puisque l ordre des attributs n est pas fixé, une ligne est plutôt une fonction l : {A 1,..., A p } Dom(A 1 ) Dom(A 2 ) Dom(A p ) avec comme contrainte le fait que l(a i ) Dom(A i ). Comme il est plus facile de parler du tuple (Mathilde, Dufour, PCSI, 2, Calmette, 18) que de l application qui a chacun des attributs de la table associe sa valeur, on sacrifiera un peu à la rigueur mathématique ici. Relation. On appelle relation (ou table) un ensemble fini de p-uplets de Dom(A 1 ) Dom(A p ), qu on notera souvent R dans ce cours. Pour préciser que la relation est associée au schéma relationnel S, on notera R(S). Les éléments de R(S) (les lignes dans le tableau ci-dessus) sont appelés valeurs ou enregistrements. 3.3 Contraintes en notations. On a déja dit qu il n y avait pas d attribut en double. Il n en est en effet pas question, ils risqueraient d être affectés de valeurs différentes dans des tuples. Pour t un tuple de R(S), on note t[a i ] la composante du couple associée à l attribut A i. Par extension, si X = (B 1,..., B n ) S, on note t[x] le n-uplet (t[b 1 ],..., t[b n ]) Définition 1. Dans une relation R(S), les enregistrements forment un ensemble. Ceci a deux implications : Visuellement, on ne peut avoir deux lignes égales dans le tableau (ce qui serait d ailleurs synonyme de redondance des données). Ceci correspond à l aspect fonctionnel des tuples : avec S = {A 1,..., A p }, si t[a 1,..., A p ] = t [A 1,..., A p ] alors t = t. Une autre caractérisation est que deux enregistrements doivent différer d au moins un attribut. L ordre des lignes n est pas fixé. Bien entendu une présentation des données dans un tableau aura un ordre des attributs et un ordre des tuple mais ces ordres de présentations sont du à l ordre physique des données, ou le résultat d un traitement particulier lors d une requête. En particulier, il n est pas garanti a priori par le SGBD. Svartz Page 4/15 2014/2015
3.4 Clés Pour garantir la non-répétition des enregistrement, les bases de données réelles contiennent un concept de clé qui doit être pensé dès la conception des bases de données, et indiqué à la création. Ce concept a également son imporance lors de l utilisation de relations multiples. Définition 2. Une super-clé d une relation R est un ensemble X d attributs tel que t, t R t[x] = t [X] = (t = t ) Ainsi, si les deux enregistrements sont égaux sur les attributs de X alors ils sont égaux partout. En raison de la contrainte d ensemble pour les enregistrements, l ensemble de tous les attributs est toujours une super-clé. Dans l exemple ci-dessus {prenom} et {nom} ne sont pas des super-clés, contrairement à {nom, prenom}, par exemple. Définition 3. Une clé candidate d une relation r est une super-clé minimale (pour l inclusion). K est donc une clé candidate si K est une super-clé. Pour tout K inclus dans K, K n est pas une super-clé. Dans l exemple ci-dessus, {nom, prenom} est une clé candidate. Proposition 1. Une super-clé qui ne contient qu un seul attribut est toujours une clé candidate. Par contre une telle super-clé n existe pas toujours, il n y en a pas dans le tableau Éleves ci-dessus. À Masséna, le numéro d une classe (831, 833...) est une super-clé : Table Classes classe filière numéro 831 MPSI 1 832 MPSI 2 833 PCSI 1 834 PCSI 2 Définition 4. Parmi les clés candidates on en choisit une : c est la clé primaire. Pour indiquer la clé primaire on souligne les attributs correspondants dans la table. Indiquer au système une clé primaire pour chaque table permet une indexation des données à l aide de cette clé, ce qui renforce l efficacité des procédures d interrogation de la table. Cette indication doit se faire à la création de la table. Dans la pratique on évitera les clés primaires qui ne seraient primaires que «par accident» : on pourrait insérer des données supplémentaires qui feraient perdre le caractère primaire des clés (en pratique, le serveur interdira le rajout de ces données). Par exemple, dans la table Éleves, le couple {nom,filière} est une clé candidate, mais rien ne garantit qu elle puisse le rester! On introduit souvent un attribut supplémentaire (commençant souvent par id), dans la définition de la relation qui sera un entier qu on incrémentera à chaque ajout d un tuple. Ce sera la clé primaire. Voici une modification de la relation eleve avec ce principe : Table eleve id_eleve prenom nom filiere numero lycee_origine note_bac 1 Mathilde Dufour PCSI 2 Calmette 18 2 Léa Dupond MPSI 2 Massena 14 3 Paul Dugommier PCSI 1 Massena 12 4 Mathilde Dugommier MPSI 1 Calmette 15 5 Clément Durand PCSI 1 Parc Imperial 13 On ne le fera pas systématiquement, notamment lorsque dans la relation se trouve des clés étrangères, concept que l on détaillera plus tard. 4 Algèbre relationnelle simple L algèbre relationnelle sert à formaliser les questions que l on peut poser à une relation ou, comme plus tard, à un ensemble de relation. Elle exprime ce que l on fait ; le calcul relationnel exprime ce que l on veut. Le langage SQL est l expression concrète des opérations de l algèbre relationnelle. Svartz Page 5/15 2014/2015
4.1 Définition L algèbre relationnelle est un ensemble d opérateurs que l on peut appliquer à des relations, et dont le résultat est une relation. Comme le résultat est toujours une relation on pourra combiner les opérateurs : on forme ainsi, à partir d opérateurs élémentaires, des requêtes élaborées. L objectif est de pouvoir exprimer toute manipulation raisonnable par une expression algébrique des opérateurs élémentaires. Voici des exemples de questions qu on peut demander au serveur de bases de données. Quels sont les élèves venant du lycée Calmette? Ceux de MPSI 1? Quelle est la moyenne au baccalauréat des élèves de Masséna? Qui sont ceux qui ont obtenu une mention? Étant donnés deux relations pour les élèves de Masséna en 2013-2014 et 2014-2015, qui sont les 5/2? La troisième opération demande d avoir deux relations, mais on va quand même y répondre ici. 4.2 Opérateurs ensemblistes Un premier type d opérateur combine 2 relations qui ont le même schéma ; on les utilisera surtout pour assembler les résultats d autres requêtes. R et R sont deux relations ayant le même schéma (c est-à-dire les mêmes attributs). R R est la relation de même schéma dont les tuples sont ceux qui appartiennent à R ou à R R R est la relation de même schéma dont les tuples sont ceux qui appartiennent à R et à R. R\ R est la relation de même schéma dont les tuples sont ceux qui appartiennent à R mais pas à R. Il suffit donc deux faire l intersection de deux relations pour avoir les élèves ayant fait 5/2 en 2014-2015. 4.3 Opérateurs spécifiques Les opérateurs étudiés ici sont ceux qui utilisent la structure des relations. Par exemple la question «Quels sont les élèves en MPSI 1?» se traduit par : donner les noms et prénoms (projection) des élèves de Masséna étant dans la classe 831 (sélection). On reprend notre table suivante ici : Table eleve prenom nom filiere numero lycee_origine note_bac Mathilde Dufour PCSI 2 Calmette 18 Léa Dupond MPSI 2 Massena 14 Paul Dugommier PCSI 1 Massena 12 Mathilde Dugommier MPSI 1 Calmette 15 Clément Durand PCSI 1 Parc Imperial 13 Projection. La projection consiste à ne garder qu une partie des attributs. Pour X S un ensemble d attributs, On note π X (r) la relation extraite de R avec les mêmes tuples restreints à l ensemble X. Par exemple, π nom,prenom (eleve) est la table suivante : π X (R) = {t[x] t R} π nom,prenom (eleve) prenom nom Mathilde Dufour Léa Dupond Paul Dugommier Mathilde Dugommier Clément Durand Rappelons que dans une relation, les tuples forment un ensemble. Il se peut donc que π X (R) ait moins d éléments que la table initiale. (En fait le nombre d éléments est conservé si et seulement si l ensemble d attributs X est une super-clé de la relation). π prenom (eleve) prenom Mathilde Léa Paul Clément Svartz Page 6/15 2014/2015
Sélection. La sélection consiste à ne garder que les tuples qui vérifie une propriété. On note σ P (R) la relation extraite de R avec les mêmes attributs dont les tuples vérifient la propriété P. σ P (R) = {t R P(t)} Les propriétés élémentaires sont de la forme EθE où θ un opérateur de comparaison (=, <,, >, ) et E et E des expression construites à partir des attributs et des constantes avec des fonctions usuelles. Une propriété composée avec des connecteurs logiques (ET, OU et NON, aussi notés, et ) correspond à des unions et intersections et peut être écrite directement. Par exemple σ P P (R) = σ P (R) σ P (R). On utilisera donc plutôt des conditions composées, qui ont une écriture plus courte. Par exemple, les élèves de MPSI dans la table ci-dessus est : σ filiere= MP SI OUprenom= Mathilde (eleve) prenom nom filiere numero lycee_origine note_bac Mathilde Dufour PCSI 2 Calmette 18 Léa Dupond MPSI 2 Massena 14 Mathilde Dugommier MPSI 1 Calmette 15 Sélection et projection vont souvent ensemble : si on s intéresse aux noms et prénoms des élèves de MPSI, on obtient : π nom,prenom (σ filiere= MP SI (eleve)) prenom nom Léa Dupond Mathilde Dugommier Renommage. Le renommage consiste à renommer un attribut. Ce sera utile lors de produits de tables lorsque deux tables ont des attributs portant le même nom mais correspondent à des données différentes. Si A S où S est le schéma de R(S) et B / S on peut renommer A en B, pour obtenir un élément de R (S ) de schéma S = (S\{A}) B : ρ A B (R) = {t r R, t[b] = r[a] et C S\{A}, t[c] = s[c]} Par extension, on notera ρ A1,...,A p B 1,...,B p pour ρ A1 B 1 ρ Ap B p (en supposant les A i et B j tous distincts) Table classe id_classe filière numéro 831 MPSI 1 832 MPSI 2 833 PCSI 1 834 PCSI 2 Table ρ filiere sec,numero nb (classe) id_classe sec nb 831 MPSI 1 832 MPSI 2 833 PCSI 1 834 PCSI 2 5 SQL 5.1 Introduction La présentation des bases de données qui a été faite correspond à une abstraction. Dans la pratique chaque éditeur d un logiciel de gestion de base de données organise les données afin d optimiser leur accès. En général ces données sont stockées à distance et l utilisateur envoie des requêtes pour obtenir les informations souhaitées : c est l architecture client-serveur. Dans la pratique il existe souvent un programme intermédiaire entre l utilisateur et les données : c est l architecture trois tiers (3 intervenants). Dans le cas de l architecture client-serveur (et aussi entre le tiers intermédiaire et le serveur de données) il s est produit un événement inhabituel : une norme universelle a été établie qui permet d écrire des requêtes de la même façon quel que soit le logiciel : c est SQL, pour Structured Query Langage. Ce langage reprend la structure de l algèbre relationnelle en y ajoutant des moyens de calculs et autres améliorations. Il le fait dans une formulation plus proche d un langage humain (l anglais) en structurant les requêtes dans un modèle simple. Bien entendu chaque éditeur optimise les questions pour donner des réponses le plus rapidement possible, ajoute des améliorations supplémentaires mais presque tous contiennent le langage tel qu il est normalisé. Svartz Page 7/15 2014/2015
5.2 Syntaxe Les représentations des relations se font avec le modèle du tableau. En SQL on parlera de tables à la places de relations colonnes à la places d attributs lignes à la places de tuples. La forme générale d une requête en SQL est SELECT... FROM table... ; Les mots-clés de SQL sont usuellement écrits en majuscule mais ce n est pas obligatoire. Le mot-clef principal est SELECT, qu on retrouvera en tête de toutes nos requêtes SQL. Les requêtes se terminent par un point-virgule. Projection. Basiquement, SELECT permet de faire une projection (attention à ne pas confondre avec la sélection...). Il suffit d indiquer les attributs que l on veut garder juste après SELECT : SELECT A1,...,Ap FROM table ; Les attributs (colonnes) à afficher sont énumérés et séparés par une virgule. Si on ne veut pas effectuer de projection (c est à dire garder tous les attributs), on peut utiliser le joker * au lieu d énumérer tous les attributs un à un. SELECT * FROM table ; Le mot-clef FROM permet de spécifier le nom de la table à utiliser. Attention : en SQL, les résultats d une requête ne forment pas une table car les doublons résultant de projections ne sont pas supprimés. Il faut utiliser le mot clef DISTINCT pour supprimer les doublons. >>> SELECT prenom FROM eleve ; "Mathilde" "Léa" "Paul" "Mathilde" "Clément" >>> SELECT DISTINCT prenom FROM eleve ; "Mathilde" "Léa" "Paul" "Clément" Sélection. La sélection se fait avec le mot-clef WHERE, placé après le nom de la table. Comme en Python, on utilise les comparateurs = et!= pour l égalité et la différence. Si le domaine de l attribut le permet, on peut utiliser d autres comparateurs (>, <, >=, <=) et même des fonctions arithmétiques. Une condition complexe peut être exprimée à l aide de conditions plus simples et des des connecteurs logiques ET, OU, et NON, qu on notera aussi, et. Renommage. On peut renommer un ou plusieurs attributs avec AS ou même en juxtaposant le nouveau nom à droite de l ancien. Ceci sera particulièrement utile lorsqu on utilisera plusieurs tables dont les noms d attributs sont les mêmes, ou lorsqu on fera des sous-requêtes. La syntaxe générale est : SELECT A1 as B1,..,Ai as Bi, C1,..,Cj FROM table ; Le AS est facultatif, mais c est plus lisible. Par exemple : SELECT prenom p, nom n, notebac/2 note_sur_10 FROM eleve ; produit la table suivante : Table ρ note_bac note_sur_10 (π nom,prenom,note_bac/2 (eleve)) p n note_sur_10 Mathilde Dufour 9 Léa Dupond 7 Paul Dugommier 6 Mathilde Dugommier 7 Clément Durand 6 La projection est un peu abusive ici car on fait une opération arithmétique en plus. Svartz Page 8/15 2014/2015
Opérations ensemblistes. Si on veut combiner plusieurs requêtes on peut les assembler avec UNION, INTERSECT ou EXCEPT, qui réalise l union, l intersection et la différence. Ceci dit, lorsqu on a qu une seule table il est plus simple (et préférable) de combiner les conditions. 6 Agrégats et fonctions d agrégation 6.1 Agrégats Définition 5. Soit f : E n F. On dit que f est symétrique si pour tout n-uplet (x 1,..., x n ) de E, tout i j, on a f(x 1,..., x i 1, x i, x i+1,, x j 1, x j, x j+1,..., x n ) = f(x 1,..., x i 1, x j, x i+1,, x j 1, x i, x j+1,..., x n ). Puisque les transpositions engendrent le groupe symétrique, il est équivalent de dire que le résultat ne change pas lorsqu on permute les arguments. Définition 6. On appelle fonction d agrégation E F une suite (f n ) n 1 de fonctions symétriques de E n F. Ça paraît un peu étrange, mais c est légitime. Voila des exemples de fonctions d agrégation : la somme (on a f n (x 1,..., x n ) = x i ), le produit, le max, le min, le cardinal (dans ce cas f n est la fonction constante égale à n), la moyenne (sur des ensembles où ces opérations sont possibles)... On peut utiliser de telles fonctions en regroupant les données par paquets pour obtenir une nouvelle table. Si f est une fonction d agrégation, X est un ensemble d attributs d une relation R de schéma S, et A S un attribut n appartenant pas à X on note, pour chaque tuple t 0 de valeurs de X, f(t 0, A) la valeur de la fonction f appliquée à l attribut A pour la relation σ t[x]=t0 (R) c est-à-dire appliquée à l ensemble des tuples qui prennent les valeurs t 0 pour les attributs de X. On introduit une nouvelle opération, l agrégation notée X γ f(a). L image de R par cette opération est une relation de schéma X {f(a)}. Xγ f(a) (R) = {t; s R, t[x] = s[x], t[f(a)] = f(s[x], A)} En pratique : on regroupe la relation selon les valeurs des attributs de X et on calcule f(a) pour tous les ensembles de lignes définies par ces regroupements. Exemple : filiere γ MOY ENNE(notebac) (eleve) est une relation regroupant la moyenne des notes au bac suivant les filières. γ MOY ENNE(notebac) (eleve) est une relation avec un unique tuple de taille 1, donnant la moyenne des notes au bac des élèves. On aura tendance à ne pas noter l ensemble vide. Remarquez qu un tel tuple s identifie avec un élément du domaine de son unique attribut. 6.2 SQL Les résultats d une requête seront souvent utilisés ensuite, par exemple à des fins statistiques. SQL contient la possibilité de faire quelques uns de ces calculs. Les fonctions disponibles (de base) sont le comptage, c est-à-dire le nombre de lignes : COUNT le maximum des éléments dans une colonne : MAX le minimum des éléments dans une colonne : MIN la somme des éléments d une colonne : SUM la moyenne des éléments d une colonne (sum/count) : AVG Le résultat est une table avec une unique ligne et une unique colonne, que l on peut utiliser comme valeur. Si f est une de ces fonctions on l emploie sous la forme SELECT f(attribut) FROM table WHERE condition ; Par exemple, avec la relation eleve, SELECT AVG(notebac) FROM eleves produit 14.4. Le mot-clef GROUP BY sert à indiquer sur quels attributs sont effectués les regroupements. Par exemple : SELECT AVG(notebac) FROM eleves GROUP BY filiere ; produit une table ayant une unique colonne : Svartz Page 9/15 2014/2015
AVG(notebac) 14.5 14.333333333333334 Ici on a en fait fait une sélection supplémentaire, il est ici a priori plus intéressant d afficher aussi la filière SELECT filiere,avg(notebac) FROM eleves GROUP BY filiere ; qui produit : 6.3 Sélection après agrégation filiere AVG(notebac) MPSI 14.5 PCSI 14.333333333333334 Pour faire une sélection après une opération d agrégation, on utilise HAVING. Par exemple, à la suite de la requête précédente, on pourrait vouloir garder uniquement les filières ayant une moyenne supérieure à 14.4. Cela correspond en algèbre relationnelle à la composition σ MOY ENNE(notebac)>14.4 filiere γ MOY ENNE(notebac) (eleve). En SQL, on fait la distinction : on utilise le mot-clef HAVING pour sélectionnier après une agrégation. La syntaxe correspondante est la suivante : SELECT filiere,avg(notebac) FROM eleves GROUP BY filiere HAVING AVG(notebac)>14.4 ; qui produit : filiere AVG(notebac) MPSI 14.5 Il est ici très commode de procéder à un renommage : garder un attribut qui s appelle AV G(notebac) est un peu pénible. SELECT filiere,avg(notebac) AS moy FROM eleves GROUP BY filiere HAVING moy>14.4 ; qui produit : Ceci correspond en algèbre relationnelle à la composition filiere moy MPSI 14.5 σ moy>14.4 ρ MOY ENNE(notebac) moy filiere γ MOY ENNE(notebac) (eleve) Rappellons qu en SQL, le mot-clé AS est facultatif, on aurait pu juxtaposer moy à AVG(notebac). Pour faire des sélections, on a donc deux outils à notre disposition : WHERE et HAVING. WHERE sélectionne avant une agrégation (on dit en amont), et HAVING en aval. Lorsqu on a le choix, il vaut mieux sélectionner en amont, pour n effectuer l agrégation que sur un nombre minimal de lignes. Évidemment dans l exemple ci-dessus, la sélection en aval est tout à fait légitime car on ne pouvait pas faire de sélection en amont. 7 Affichage des résultats Cette section n est pas vraiment de l algèbre relationnelle puisqu on ne raisonne plus sur une relation en temps que simple ensemble, mais comme ensemble ordonné. 7.1 Ordonner les résultats avec ORDER BY La syntaxe en SQL pour ordonner les résultats se fait à l aide du mot-clé ORDER BY, couplé à une expression arithmétique des attributs. L expression sera souvent un attribut lui-même : SELECT * FROM eleve ORDER BY notebac ; Svartz Page 10/15 2014/2015
produit à l affichage : prenom nom filiere numero lycee_origine note_bac Paul Dugommier PCSI 1 Massena 12 Clément Durand PCSI 1 Parc Imperial 13 Léa Dupond MPSI 2 Massena 14 Mathilde Dugommier MPSI 1 Calmette 15 Mathilde Dufour PCSI 2 Calmette 18 Deux petites subtilités : on peut spécifier si l on veut le résultat dans l ordre croissant ou décroissant à l aide des mots clés ASC et DESC (pour ascendant et descendant) juste après l expression. Comme on le voit sur l exemple précédent, le comportement par défaut est ASC. si on met plusieurs expressions après ORDER BY, séparés par des virgules (typiquement plusieurs arguments), la relation est triée pour l ordre lexicographique (on compare la première expression, puis en cas d égalité la deuxième, etc...) Voici un exemple récapitulant un peu tout ça : des points du plan à coordonnées entières, avec un renommage. La requête Table point nom abscisse ordonnee A 0 0 B 1 0 C 0 1 D 2-3 E -3-2 SELECT nom,abscisse a, ordonnee o FROM point ORDER BY a*a+o*o DESC,ABS(a) ASC ; produit la table suivante : nom a o D 2-3 E -3-2 C 0 1 B 1 0 A 0 0 Les points sont triés par distance à l origine décroissante. En cas d égalité, ils sont triés par valeur absolue d abscisse croissante. 7.2 Limiter l affichage avec LIMIT et OFFSET Ce point est hors programme, mais n est pas dur à comprendre. Il est précisé pour la culture. On peut limiter le nombre de résultats d une requête SQL en utilisant LIMIT : en ajoutant LIMIT n avec n un entier, on limite le nombre de résultats à n. Il est aussi possible de préciser un OFFSET : avec OFFSET m on ignore les m premiers résultats. Ne pas mettre OFFSET est donc équivalent à OFFSET 0. En reprenant l exemple précédent, la requête : SELECT nom,abscisse a,ordonnee o FROM point ORDER BY a*a+o*o DESC, ABS(a) ASC LIMIT 2 OFFSET 1 ; produit : nom a o E -3-2 C 0 1 On limite le nombre de lignes à 2, et on ignore la première (D ici). LIMIT et OFFSET sont utilisables sans préciser d ordre, mais rappelez-vous que l ordre de l affichage n est pas garanti (il dépend du stockage interne de la BDD) et c est donc en général peu pertinent d en faire usage sans ORDER BY. Svartz Page 11/15 2014/2015
8 Composition de requêtes Ceci est un point important, et on commence à voir l intérêt des bases de données. On a déja vu HAVING, qui effectue une sélection en aval d une agrégation : SELECT filiere,avg(notebac) moy FROM eleve GROUP BY filiere HAVING moy>14.4 ; Voyons un exemple équivalent à celui plus haut, mais sans HAVING : SELECT filiere,moy FROM (SELECT filiere,avg(notebac) moy FROM eleve GROUP BY filiere) WHERE moy>14.4 ; Ici, on effectue une première requête (à l intérieur des parenthèses) produisant des lignes de la forme filiere, moyenne, puis on réutilise immédiatement la table produite dans une nouvelle requête. Celle-ci est équivalente à la première et produit le même résultat, et peut-être vue comme une traduction SQL différente de la composition σ moy>14.4 ρ MOY ENNE(notebac) moy filiere γ MOY ENNE(notebac) (eleve) Que ce soit en algèbre relationnelle ou en SQL, ceci se justifie bien : appliquer les opérateurs de l algèbre relationnelle à une relation produit une relation, appliquer des requêtes à une table produit une table. Un autre exemple est le suivant : quels sont les élèves ayant eu la plus haute note au bac? Ici, il faut récupérer d abord la plus haute note au bac, puis refaire une requête pour sélectionner les élèves ayant eu cette note. En SQL, on obtient : SELECT * FROM eleve WHERE notebac=(select MAX(notebac) FROM eleve) ; Ici, on utilise l identitification entre une table à 1 ligne et 1 colonne et la valeur de cette case. Attention, on pourrait être tenté d écrire quelque chose comme SELECT nom,prenom,max(notebac) FROM eleve ; qui n a pas vraiment de sens en algèbre relationnelle, mais fonctionne en SQL. Le résultat produit est invariablement une table avec une seule ligne : on obtient les nom et prénom d un seul élève ayant eu la meilleure note au bac (avec cette note). Bref, on peut faire des sous-requêtes en les plaçant entre parenthèses. On a vu qu on pouvait utiliser comme valeur une table à une ligne et une colonne pour faire une sélection. Par extension, on peut utiliser une requête produisant une table à une seule colonne avec le mot-clef IN. Par exemple, à la question «Quels sont les élèves de PCSI qui ont même prénom qu un élève de MPSI?», on peut répondre avec la requête : SELECT * FROM eleve WHERE filiere="pcsi" AND prenom IN (SELECT prenom FROM eleve WHERE filiere="mpsi") Le mot-clé IN est hors programme. 9 Produit cartésien et jointure 9.1 Introduction Pour éviter la redondance des informations il est en général préférable d organiser nos données en différentes tables, plutôt qu en une unique base de données (plate). Les principes guidant cette organisation sont plutôt hors programme, on va simplement étudier ici l utilisation simultanée de plusieurs tables, comme celles-ci dessous. Table Eleve prénom nom id_classe id_lycee Mathilde Dufour 834 1 Léa Dupond 832 2 Paul Dugommier 833 2 Mathilde Dugommier 831 1 Clément Durand 833 3 Table Lycee id_lycee nom_lycee 1 Calmette 2 Massena 3 Parc Imperial Table Classe id_classe filière numéro 831 MPSI 1 832 MPSI 2 833 PCSI 1 834 PCSI 2 Svartz Page 12/15 2014/2015
9.2 Produit Le premier moyen d assembler deux relations est d en faire le produit cartésien. Définition 7 (Produit de deux relations). Si R est une relation de schéma S et R une relation de schéma S avec S S = alors le produit de R et R est la relation R R de schéma S S définie par R R = {u; u[s] R, u[s ] R } La condition R R = n est en fait pas contraignante : on peut procéder par renommage pour l assurer. Pour éviter les homonymies, on notera en général R.A et R.A les attributs de R et R. Une telle table a donc pour cardinal le produit #R #R, ce qui peut facilement devenir très lourd avec des tables de taille conséquente. Voici le début de la table eleve lycee : Table Eleve lycee prénom nom id_classe id_lycee id_lycee nom_lycee Mathilde Dufour 834 1 1 Calmette Mathilde Dufour 834 1 2 Massena Mathilde Dufour 834 1 3 Parc Imperial Léa Dupond 832 2 1 Calmette Léa Dupond 832 2 2 Massena On remarque qu il y a deux attributs de même nom (ce qui est impossible) : en fait les noms de ces attributs sont plutôt Eleve.id_lycee et lycee.id_lycee (la présentation sous cette forme suit ce qu il se passe en SQL). 9.3 Division Il existe une fonction réciproque du produit, la division, dans l algèbre relationnelle. Elle est l analogue de la division euclidienne vis à vis de la multiplication sur les entiers. La division de a par b est le plus grand entier q tel que bq a. C est la même chose avec des relations, en remplaçant la relation d ordre par l inclusion. Définition 8 (Division de deux relations). Si R est une relation de schéma S et R une relation de schéma S avec S S, alors la division de R par R est la relation R R de schéma S\S définie par R R = {u t R, (u, t) R} De manière équivalente, on peut aussi définir R R comme la plus grande relation R de schéma S\S telle que R R R. Avec cette définition alternative, le lien avec la division euclidienne apparaît plus clairement. Par exemple, la division de la relation σ id_classe,id_lycee (eleve) par σ id_lycee (lycee) donne l ensemble des classes possédant un élève en provenance de chacun des lycées de la table lycee. Avec les petites tables ci-dessus cette division donne une relation vide, mais il suffirait d ajouter un élève en 833 provenant de Calmette pour que la 833 se retrouve dans σ id_classe,id_lycee (eleve) σ id_lycee (lycee) 9.4 Jointure naturelle Visiblement, dans l exemple de produit cartésien ci-dessus, un bon nombre de lignes n ont pas d intérêt réel : ce sont celles pour lesquelles eleve.id_lycee est différent de lycee.id_lycee. Il est ici naturel lors du produit d identifier les colonnes des attributs qui portent le même nom : on parle de jointure naturelle. Définition 9 (Jointure naturelle). Pour R et R deux relations de schémas S et S avec S S = S, on définit la jointure naturelle de R et R comme la relation R R de schéma S S définie par On a déja vu deux cas particuliers de cette notion : si S S = on retrouve le produit de R et R. si S = S on retrouve l intersection de de R et R. Voici un exemple de jointure naturelle : R R = {u u[s] R et u[s ] R } Svartz Page 13/15 2014/2015
9.5 Jointure Table Eleve Lycee prénom nom id_classe id_lycee nom_lycee Mathilde Dufour 834 1 Calmette Léa Dupond 832 2 Massena Paul Dugommier 833 2 Massena Mathilde Dugommier 831 1 Calmette Clément Durand 833 3 Parc Impérial La jointure n est, d un point de vue algébrique, qu une abréviation : elle consiste à sélectionner dans le produit cartésien. Définition 10 (Jointure de deux relations). Pour R et R sont deux relations de schémas S et S avec S S =, et C une condition booléenne portant sur S S alors la jointure de R et R selon C est la relation R C R de schéma S S définie par R C R = σ C (R R ) Si C est la condition triviale (toujours vraie) on retrouve le produit cartésien standard. Si on considère que les noms des attributs d une relation R sont R.A au lieu de A alors la jointure naturelle ressemble à une jointure avec comme condition la conjonction (liaison par l opérateur ET) des égalités R.A i = R.A i pour les attributs A i appartenant à R R. La différence est qu alors les colonnes égales sont répétées : la jointure naturelle est plus... naturelle. 10 Tables multiples dans SQL 10.1 Produit cartésien La traduction en SQL du produit cartésien est très simple : il suffit d énumérer les différentes tables dans la clause FROM. SQL considère les noms des colonnes de la table T sous la forme T.nom, il n y a pas de noms identiques. Cependant, lors de l affichage, le titre de la colonne ne sera que le nom de l attribut et on peut croire que la contrainte d ensemble pour les attributs n est pas respectée. Lorsqu on aura des noms d attributs égaux, il faudra donc spécifier la table lors de l écriture des requêtes pour lever les ambiguïtés, ce dont on peut se passer si les noms d attributs sont distincts. Il est courant de procéder à un renommage de la table elle-même pour écourter l écriture des requêtes. Voici trois exemples de requêtes simples avec des produits cartésiens : SELECT * FROM eleve,classe,lycee ; SELECT e.nom,e.prenom FROM eleve e, lycee L WHERE e.id_lycee=l.id_lycee AND L.id_lycee="Calmette" ; SELECT e.nom,e.prenom FROM eleve e, lycee L, classe c WHERE e.id_lycee=l.id_lycee AND c.id_classe=e.id_classe AND L.nom_lycee="Calmette" AND c.filiere="mpsi" AND c.numero="1" ; La première fait simplement le produit des trois tables (ce qui donne une grosse table!). La deuxième fait une sélection après un produit cartésien : en fait on fait d abord une jointure sans le dire, pour sélectionner les élèves venant du lycée Calmette. La troisième sélectionne également ceux qui sont en MPSI 1, avec une jointure supplémentaire, toujours sans le dire. 10.2 Jointure naturelle Il suffit d employer NATURAL JOIN pour effectuer une jointure naturelle entre deux tables. Voici un exemple, on reprend la requête précédente, rendue (un peu) plus courte avec NATURAL JOIN. SELECT nom,prenom FROM eleve NATURAL JOIN lycee NATURAL JOIN classe WHERE id_lycee="calmette" AND filiere="mpsi" AND numero="1" ; 10.3 Division Elle n existe pas en SQL, et existe en algèbre relationnelle pour garantir une certaine complétude des opérations. On peut par exemple réaliser une division avec des sous-requêtes, des jointures et la fonction d agrégation de comptage, mais ce n est pas simple et sort du cadre de ce cours. Svartz Page 14/15 2014/2015
10.4 Jointure La traduction de la jointure en SQL est JOIN. On spécifie la condition de jointure avec ON : table1 JOIN table2 ON condition Bien que cela soit possible il n est pas recommandé de placer toutes les sélections dans la clause ON à la place de la clause WHERE. Typiquement pour une équijointure (jointure avec condition d égalité entre deux attributs), on placera la condition d égalité de deux colonnes dans la clause ON, et les autres conditions de sélection dans la clause WHERE. L intérêt d une jointures est de structurer plus clairement les requêtes, bien qu on puisse s en passer en faisant des produits cartésiens et en sélectionnant, comme on l a fait plus haut. Voici encore une variante de la requête qu on a vu plus haut avec produit cartésien et jointure naturelle : SELECT nom,prenom FROM eleve e JOIN lycee L ON e.id_lycee=l.id_lycee JOIN classe c ON e.id_classe=c.id_classe WHERE e.nom_lycee="calmette" AND c.filiere="mpsi" AND c.numero="1" ; Svartz Page 15/15 2014/2015