Les nouveautés de MySQL 5.0Date de publication : 03/11/2005
Par
Maximilian (autres articles) La dernière version de production de MySQL, sortie en Octobre 2005, représente certainement l'évolution la plus significative de ce SGBD depuis ses débuts. Cet article vous propose d'explorer ses principales nouvelles fonctionnalités de manière concrète. Introduction Un peu d'exercice A. Les procédures stockées 1. Définition 2. En pratique 3. Restrictions B. Les triggers 1. Définition 2. En pratique 3. Restrictions C. Les vues 1. Définition 2. En pratique 3. Restrictions D. Le dictionnaire INFORMATION_SCHEMA 1. Définition 2. En pratique Conclusion IntroductionBien que MySQL 5 compte encore des lacunes importantes, les progrès effectués en termes de respect du standard SQL ne sont pas négligeables. En effet, le SGBD prend désormais en charge les fonctionnalités précieuses que sont les procédures stockées, les vues, ainsi que des triggers rudimentaires et dans une moindre mesure le dictionnaire de données information_schema. Je vous propose d'aborder ces mécanismes à travers des définitions techniques et un cas pratique. Un peu d'exercicePour illustrer tout cela, prenons un exemple concret et plutôt ludique : la gestion des matches de Ligue 1 du championnat de France de football. Site web de pronostics, portail sportif, jeu de foot, à vous d'imaginer le contexte... Pour l'instant nous allons nous contenter de 2 tables simples : celle des equipes et celle des rencontres. Voici les ordres de création de la base :
Les données ressembleront à cela : Equipes ![]() Rencontres ![]() Jusqu'ici, rien de bien sorcier. Plongeons-nous maintenant dans les possibilités offertes par MySQL 5. A. Les procédures stockées1. DéfinitionLes procédures et fonctions stockées (Stored Procedures, en abrégé SP) sont du code applicatif entreposé et exécuté au sein du serveur de base de données. Ce code combine commandes SQL, structures de contrôle, variables, tout comme une fonction ou méthode dans n'importe quel langage de programmation. Les procédures MySQL sont écrites selon la syntaxe standard SQL:2003. Mais pourquoi confier au SGBD des tâches normalement dévolues à l'application cliente, me direz-vous ? Cela présente essentiellement 3 avantages :
2. En pratiqueRevenons à notre terrain de jeu et créons dans la base ligue1 une première procédure stockée :
Comme vous pouvez le voir, la syntaxe est proche de ce que peut être une fonction ou une méthode dans un langage de programmation. La procédure prend en entrée des paramètres d'un type donné, son corps est délimité par les instructions BEGIN et END à l'intérieur desquelles on effectue un certain nombre de traitements. Ici en l'occurrence, on se contente d'insérer une nouvelle équipe dont le nom, le stade et la ville ont été passés en paramètre.
Bon, nous avons créé la procédure mais maintenant, comment s'en servir ? Rien de plus simple. On utilise l'instruction SQL CALL sur la SP en donnant les valeurs voulues en paramètre :
Laissons là cette procédure stockée qui n'a pas grande utilité et passons aux matches. En toute logique, on va les renseigner en deux temps :
La première opération peut être effectuée via la procédure stockée suivante :
Et appelée comme ceci :
La gestion de l'issue du match va quand à elle faire l'objet d'une procédure plus complexe puisque la mise à jour ne concerne pas seulement la table rencontre. Elle affecte aussi les points du championnat, donc la table equipe :
En clair : on met à jour la table rencontre avec les valeurs des scores passées en paramètre, puis on rajoute un point à chaque équipe en cas de match nul, ou sinon 3 points au vainqueur.
Les développeurs ne seront pas dépaysés par l'utilisation de la condition IF - THEN - ELSE qui reste ici assez classique. Il peut également être intéressant d'initialiser tous les matches dès le début de saison, avant de les renseigner. Concrètement, cela signifie insérer une rencontre pour chaque couple équipe domicile/équipe visiteurs distinct :
Ce code mérite quelques explications. Tout d'abord remarquez que la procédure ne prend aucun paramètre, ce qui est normal puisque tout ce dont on a besoin pour l'initialisation des matches se trouve dans la table equipe. L'instruction DECLARE sert, comme son nom l'indique, à déclarer une variable interne à la procédure. Les déclarations doivent être placées au début, avant les instructions de traitement. On peut déclarer des variables de type de base (INT, VARCHAR, etc.) comme dans les 2 premières lignes mais aussi des structures plus complexes comme les curseurs (CURSOR) et les HANDLERS. Un curseur est un objet permettant de parcourir séquentiellement le jeu de résultats retourné par une requête SQL. En l'occurrence, nous avons besoin de créer deux curseurs cur_domicile et cur_visiteur portant sur la même requête SELECT id_equipe FROM equipe. Le parcours du deuxième curseur est placé à l'intérieur du premier, de la même manière que nous aurions imbriqué deux boucles for dans un autre langage pour passer en revue toutes les combinaisons de couples (equipe1, equipe2). Ainsi, pour chaque équipe domicile on parcourt toutes les équipes visiteuses qui vont jouer contre elle (c'est à dire toutes sauf elle-même) et on insère un nouveau match à chaque fois. Le curseur est ouvert via l'ordre OPEN et fermé avec CLOSE. La syntaxe d'itération sur un curseur est un peu particulière ; elle repose sur une simple boucle WHILE dans laquelle on fait avancer le curseur (FETCH), et sur un HANDLER. Ce dernier sert à déterminer ce qui se passe lorsque le SQLSTATE NOT FOUND est atteint, c'est à dire quand le curseur est au bout du jeu de résultats. En général on sort de la boucle WHILE.
Fonctions stockées : les fonctions se distinguent des procédures stockées par leur valeur de retour unique et obligatoire, et par la façon particulière de les exécuter. En effet plus question de CALL, les fonctions sont utilisables directement à l'intérieur de requêtes SQL de DML (SELECT, INSERT, UPDATE...) ce qui leur confère une grande souplesse. Une fonction bien utile pourrait par exemple être de savoir si une équipe passée en paramètre est dans les trois dernières du classement, et donc potentiellement relégable en ligue 2 :
On peut désormais appeler la fonction là où ça nous chante :
donne un aperçu des équipes relégables.
permet de supprimer, en fin de saison par exemple, les équipes relégables. 3. RestrictionsLe support des procédures stockées est sans aucun doute un grand pas pour MySQL, mais il faut dire qu'en la matière cette version 5 ne fait pas dans le pléthorique. Il manque certaines structures comme la boucle FOR, les curseurs sont limités (lecture seule, non-scrollables) et peu pratiques d'utilisation comme on l'a vu avec les handlers. Plus gênant, on déplorera que les SP soient quasi-autistes vis-à -vis de leur environnement : pas de possibilité directe d'envoyer des messages système ni de gérer ou déclencher des erreurs, sans parler de fonctions plus avancées comme la manipulation de fichiers. Un certain nombre d'ordres de maintenance tels que CHECK, LOAD DATA ou OPTIMIZE y sont eux aussi prohibés. En revanche bonne nouvelle, les ordres transactionnels (COMMIT, ROLLBACK) du moteur InnoDB sont autorisés à l'intérieur des SP MySQL.
B. Les triggers1. DéfinitionPour faire simple, les triggers (ou déclencheurs) sont des procédures qui s'activent automatiquement lorsqu'un événement donné se produit sur une table. En d'autres termes, quand une requête INSERT, UPDATE ou DELETE survient, on se réserve la posibilité d'agir avant ou après son exécution et éventuellement de modifier voire d'annuler son action. Cet outil puissant a souvent pour rôle de vérifier certaines contraintes d'intégrité sophistiquées que les contraintes SQL basiques (PRIMARY KEY, FOREIGN KEY, NOT NULL, DEFAULT...) sont incapables de gérer. Quelques exemples : un client peut avoir au maximum 5 comptes bancaires (relation de cardinalité 1,5) ; un achat peut être relié soit à une carte de fidélité soit à un coupon de réduction mais pas les deux ; il doit y avoir un intervalle de 15 minutes entre les horaires de décollage de deux avions sur la même piste ; etc. Tout ceci peut être contrôlé par des déclencheurs. Les triggers peuvent aussi servir à mettre à jour automatiquement certaines tables en fonction des modifications qui sont faites, ou à formater des données comme nous allons le voir tout de suite. 2. En pratiqueCréons un premier déclencheur qui va mettre la ville en majuscules lors de l'insertion d'une nouvelle équipe :
Comme pour les procédures stockées, le code du trigger est placé dans un bloc BEGIN ... END. Le mot-clé BEFORE indique que l'on souhaite agir avant que l'insertion ne soit réalisée. La table telle qu'elle sera après l'exécution du INSERT est désignée par l'alias new, ce qui veut dire qu'on accède aux valeurs qui vont être insérées via new.nom_colonne. Modifier la valeur de new.nom_colonne revient à transformer la requête INSERT d'origine selon nos exigences, c'est ce qu'on fait ici en forçant la mise en majuscules. Voyons si ça fonctionne :
Notre trigger a donc bien fait son oeuvre. Vous aurez peut-être remarqué que dans la procédure stockée SAISIR_RESULTAT nous ne nous sommes pas souciés de la colonne equipe.buts. En effet, comme cette donnée totalise les buts marqués par l'équipe durant le championnat, on peut tout à fait la mettre à jour à l'aide d'un déclencheur sur la table rencontre (qui sera donc activé par SAISIR_RESULTAT) :
A l'inverse de new, old fait référence à la table dans l'état où elle était juste avant que le trigger se déclenche. Dans notre exemple, on s'en sert pour savoir si le score vient d'être rempli. En effet l'UPDATE pourrait simplement modifier le nom de l'arbitre ou la date, auquel cas equipe.buts ne doit pas être mis à jour.
Vérifions maintenant l'efficacité du dispositif :
Là aussi, on constate bien que les buts ont été mis à jour en fonction du score qui vient d'être saisi. 3. RestrictionsComme je vous le disais en introduction, les triggers de MySQL 5 sont assez rudimentaires et ont un intérêt limité au regard de leurs carences. Tout d'abord vérifier des contraintes d'intégrité implique d'avoir le pouvoir de "dire non" à une requête lorsqu'elle les viole. Ceci se traduit en général par le déclenchement d'une exception système qui fait avorter la requête en cours, et par le retour d'un message d'erreur SQL personnalisé. Hélas, les procédures et déclencheurs MySQL ne permettent pour l'instant ni l'un ni l'autre. On ne peut pas non plus utiliser un ordre ROLLBACK dans le trigger pour annuler la transaction en cours. Le seul palliatif à cela consiste à provoquer artificiellement une erreur, par exemple en exécutant une requête erronée comme SELECT FROM mon_message_d_erreur, ce qui n'est évidemment pas du tout catholique. Dommage, car cette fonctionnalité est indispensable dans une grande partie des déclencheurs les plus utiles. Un certain nombre d'autres limitations achèvent malheureusement de reléguer les "gâchettes" de la 5.0 au rang de pistolets en plastique :
C. Les vues1. DéfinitionD'un point de vue logique, une vue est une sorte de table virtuelle dont le contenu correspond au résultat d'une requête SELECT. Elle se comporte comme une table en ce qui concerne l'accès à ses données, c'est à dire qu'on peut exécuter des ordres SELECT, voire UPDATE ou DELETE dessus. Les vues ont plusieurs utilités. D'une part elles constituent une commodité d'écriture pour l'utilisateur : une requête SELECT très complexe peut être manipulée à travers un nom de vue qui tient en un mot. Par ailleurs, les vues sont une façon simple et pratique de considérer les données contenues dans les tables sous un angle différent et personnalisé. Ca permet aussi de définir des privilèges beaucoup plus fins que de simples GRANT sur les tables. Par exemple, on peut refuser les droits à un utilisateur sur une table, mais à travers une vue adéquate lui autoriser la consultation d'un nombre limité de colonnes ou de lignes issues de cette table. Physiquement, on ne stocke pas durablement les données d'une vue mais juste sa définition. Lorsqu'un ordre SQL (a) va interroger une vue dont la définition est une requête (b), il y a deux possibilités sous MySQL 5.0 :
On peut spécifier un algorithme à la création de la vue (ALGORITHM = MERGE | TEMPTABLE) ou ne rien définir et laisser le moteur choisir au cas par cas. 2. En pratiqueComme un exemple vaut mieux qu'un long discours, voyons ce que cela peut apporter à notre base ligue1. On peut tirer parti des vues pour avoir un aperçu de la dernière journée de championnat :
La syntaxe est relativement simple : CREATE VIEW NOM_VUE suivi de AS et de la requête sur laquelle on veut se baser.
La vue peut être interrogée grâce à un simple SELECT, ce qui donne l'impression d'avoir une vraie table personnalisée contenant les 10 derniers matches :
Supposons maintenant que notre projet quel qu'il soit ait pris de l'importance et qu'on ait été amené à contacter les entraineurs de plusieurs clubs. On veut stocker leur numéro de téléphone personnel dans la table equipe :
Cependant, ces numéros de téléphone sont des données confidentielles qui ne doivent pas être accessibles aux utilisateurs lambda. On va donc créer une vue où ne figure pas cette colonne :
Donnons les droits sur cette vue à un nouvel utilisateur :
Et vérifions l'efficacité de notre système :
L'utilisateur user1 a donc seulement accès aux colonnes que l'administrateur a jugées utiles pour lui. Ce système amène une souplesse de contrôle très appréciable. 3. RestrictionsLes vues semblent être la nouvelle fonction la plus aboutie de cette version. On peut définir leur algorithme sous-jacent, les vues correspondant à une table unique sont updatables (avec possibilité de CHECK OPTION) et elles peuvent porter sur d'autres vues. Par contre les vues ne peuvent pas :
A l'exception de la première, ces limitations ne devraient pas s'avérer trop gênantes. D. Le dictionnaire INFORMATION_SCHEMA1. DéfinitionLa norme SQL propose d'accéder aux méta-données d'une base via le dictionnaire de données INFORMATION_SCHEMA. Dans MySQL 5.0 celui-ci est une base système à part entière au même titre que mysql. Il représente un double progrès par rapport aux versions précédentes : respect du standard contrairement aux commandes SHOW auparavant utilisées, et facilité d'interrogation via de simples requêtes SELECT. Passons en revue les méta-informations qu'on y trouve (chaque catégorie correspond à une table):
2. En pratiqueVoyons l'utilisation du dictionnaire de données à travers deux exemples. Tout d'abord, il peut être appréciable pour un utilisateur du SGBD de connaître les privilèges qu'il a sur les différentes tables. C'est ce que notre user1 va faire :
Il connait maintenant la totalité de ses privilèges sur les tables (et vues), ce qui peut être bon à savoir lorsque surviennent certains problèmes de droits. Mais notre utilisateur se pose des questions sur la vue V_EQUIPE. Que contient-elle vraiment ?
Et bien une simple requête sur INFORMATION_SCHEMA.VIEWS va le renseigner sur sa structure :
Pour résumer, INFORMATION_SCHEMA standardise les instructions d'accès aux méta-données qui existaient déjà et en apporte de nouvelles. ConclusionGrâce aux avancées que nous venons de voir, MySQL s'ouvre de nouvelles portes. Le SGBD libre parait désormais plus à même de répondre à des problématiques applicatives évoluées mettant en jeu des modèles de données complexes, même s'il lui reste du chemin à parcourir pour entrer dans la "cour des grands" des SGBD. J'espère que cet article aura été pour vous un tour d'horizon instructif des nouveautés proposées par MySQL 5.0 et que cela pourra vous aider à tirer profit de ces possibilités.
Sachez également que des évolutions tout aussi importantes (triggers améliorés, clés étrangères MyISAM, partitionnement de tables) sont prévues pour la future version 5.1.
Vous trouverez dans le manuel MySQL une référence détaillée des points abordés :
Cette page constitue une oeuvre intellectuelle protégée par les
droits d'auteurs.
Copyright © 2005 Maximilian. Tous droits réservés.
Aucune reproduction, même partielle, ne peut être faite de ce
site et de l'ensemble de son contenu : textes, documents et images sans
l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu'à 3 ans de prison et jusqu'à 300 000 € de dommages et intérets. Cette page
est déposée à la SACD.
|