Vous avez étudié jusqu'à aujourd'hui des langages de programmation (python, javascript etc...) et des langages de description (html+css...). Nous allons découvrir le langage SQL (Structured Query Language) qui est le langage de gestion et d'interrogation des bases de données.
Un des avantages de ce langage est qu'il est assez proche du langage naturel (en anglais...), et qu'il permet ainsi d'interroger et de maintenir des bases de données assez simplement. C'est donc un langage de haut niveau contrairement aux assembleurs qui sont plus "proches" de la machine.
Une autre spécificité, est qu'on peut classer SQL parmi les langages déclaratifs : les commandes SQL se basent sur le résultat que l'on veut obtenir, nous n'avons pas à décrire, ni même connaître la façon dont on va obtenir ce résultat, toute la partie algorithmique d'une recherche, du parcours d'une relation est "caché", optimisé et traité par SQL.
Dans la suite nous allons utiliser une base de données réelle pour tester et comprendre les commandes SQL. Le schéma de principe de cette base est présenté ci-dessous.
Les titres des attributs des différentes relations sont explicites.
La base contient environ 54000 acteurs, 5000 films, 2500 réalisateurs. Vous pouvez la télécharger ici.
Requêtes
Dans cette partie nous allons voir comment interroger une base de donnée en SQL.
Les opérateurs logiques AND, OR, NOT que vous connaissez déjà peuvent être utilisés en SQL, l'exemple ci dessous permet de lister les films tournés en français et sortis en 2014 :
SELECT titre FROM LesFilms WHERE vo='fr' AND anSortie='2014';
A vous maintenant de tester des requêtes répondant aux questions suivantes :
Afficher tous les titres de films tournés en 2014 en langue chinoise (zh).
Afficher tous les films tournés en 2000 en langue japonaise et ceux sortis en 1993 en français (attention à la traduction du français naturel en opérateurs logiques...)
Une des règles de construction des bases de données est de ne pas stocker une donnée pouvant être calculée à partir des données de la base. Ainsi il existe de nombreuses commandes permettant d'effectuer des calculs, appelées aussi commandes d'agrégation. Nous verrons ici quelques commandes très simples, il en existe de nombreuses autres.
COUNT
par exemple on peut compter le nombre de films de la base avec la requête
SELECT COUNT(*) FROM LesFilms;
Le symbole * représente tous les attributs, on comptera en fait le nombre de lignes de la relation LesFilms
Comme nous avons pu remarquer ci-dessus, les données présentées lors des requêtes ne sont pas triées, la commande ORDER BY permet d'avoir des résultats classés. Par exemple :
SELECT titre, recette FROM LesFilms ORDER BY recette;
présentera les films classés par recette, en affichant leur titre et leur recette.
A vous d'afficher :
Les titres des films de 1985 classés par durée
Les titres des films tournés en français classés par recette
Si l'on cherche le nombre de réalisateurs présents dans la base, on peut faire la requête suivante :
SELECT COUNT(realisateur) FROM LesRealisateurs;
Mais cette requête va compter le nombre de lignes dans la relation LesRealisateurs et non le nombre de réalisateurs. Et comme certains réalisateurs ont fait plusieurs films le résultat ne correspondra pas au nombre de réalisateurs. Il est donc nécessaire d'éliminer les doublons de ce comptage :
SELECT COUNT(DISTINCT(realisateur)) FROM LesRealisateurs;
Vous l'avez peut être remarqué, les requêtes que nous avons réalisé jusque là sont assez limitées car elle ne portent que sur une seule relation à la fois.
Par exemple nous n'avons pas pu afficher les titres des films dans lesquels a tourné Daniel Craig. Comment pourrait-on procéder ?
Lister les id des films dans lesquels à tourné Daniel Craig
Noter les id de ces films (en espérant qu'ils ne soient pas trop nombreux...)
Lister dans la relation LesFilms les titres dont l'id est dans la liste précédente
On arrivera au final avec une requête du type :
SELECT titre FROM LesFilms WHERE film_id='206647' OR film_id='10764'
OR film_id='2268' OR film_id='37724' OR film_id='17578'
OR film_id='36557' OR film_id='1995' OR film_id='65754'
OR film_id='4147' OR film_id='4858' OR film_id='612'
OR film_id='69668' OR film_id='21311' OR film_id='9667'
OR film_id='13092' OR film_id='4518' OR film_id='9389'
OR film_id='9672' OR film_id='41508' OR film_id='4836';
On est bien d'accord que d'une part ce n'est pas raisonnable et que d'autre part un langage évolué comme SQL doit bien avoir une solution à ce problème, cette solution c'est la commande JOIN.
Grâce à cette commande nous allons créer le temps de la requête une nouvelle relation issue de LesFilms et LesActeurs. Nous souhaitons que la nouvelle relation contienne les attributs des deux relations concernées, en ajoutant à chaque ligne de LesActeurs les caratéritiques du film correspondant. La commande correspondante est :
LesActeurs A JOIN LesFilms F ON (A.film_id=F.film_id)
Si on analyse cette commande, on voit que la relation LesActeurs est appelée A et LesFilms F (pour simplifier l'écriture après le ON), puis que l'on choisit le critère le jointure après la commande ON. On associe les deux relations, uniquement si l'attribut film_id est le même dans les deux tables, c'est à dire que l'on ajoute les données des films à celles des acteurs correspondants. On retrouve concrètement sur un exemple le résultat de cette jointure. Pour que cela soit lisible, il est présenté sur quelques données :
Reste ensuite à faire une requête sur cette relation "temporaire" :
SELECT titre
FROM LesActeurs A JOIN LesFilms F ON (A.film_id=F.film_id)
WHERE acteur='Daniel Craig';
On remarque ici que lorsque les requêtes deviennent longues, on gagne en lisibilité a les présenter sur plusieurs lignes, le langage SQL n'étant pas sensible à l'indentation.
A vous d'afficher :
Tous les titres de films réalisés par Tim Burton
Les titres des films, classés par recettes croissantes, dans lesquels joue l'actrice CCH Pounder
Tous les réalisateurs avec lesquels Johnny Depp a tourné un film
Nous avons vu jusque là comment interroger une base de donnée, mais une base peut être amené à évoluer de différentes façons :
en supprimant des données dans une base
en ajoutant des données dans une base
en modifiant les attributs d'une base existante
COMMIT
La commande COMMIT; permet de valider la transaction en cours, de confirmer l'écriture des modifications réalisées au cours de la transaction.
DELETE
Comme vous vous en doutez, cette commande permet de supprimer des données. Il faut bien sur la manipuler avec précautions car on peut effacer le contenu d'une relation très facilement.
DELETE FROM LesActeurs WHERE acteur='Daniel Craig';
Cette commande effacera Daniel Craig de la relation LesActeurs.
Attention, en l'absence de la commande WHERE, toute la table sera effacée !
Attention, il n'est pas possible de supprimer une donnée qui sert de clef étrangère dans une autre relation.
A vous de supprimer :
L'acteur Cedric Le Bourg des relations LesActeurs et LesRealisateurs si il est présent
La commande UPDATE permet de modifier des données déjà présentes dans les relations.
UPDATE LesActeurs SET acteur='M. Le Bourg' WHERE acteur='Cedric Le Bourg'
Sans la condition WHERE, toutes les données de l'attribut seront modifiées
On peut également modifier plusieurs attributs en même temps en séparant les égalités du SET par des virgules.
A vous de réaliser les modifications suivantes :
Remplacer le fr par français pour l'attribut vo de la relation LesFilms
Remplacer le en par anglais pour l'attribut vo de la relation LesFilms