gilles.hunault@univ-angers.fr

                                         

 

Un petit tuteur MYSQL

Valid XHTML 1.0!           Valid XHTML 1.0!

Table des matières

          1. Présentation de SQL et de MYSQL

          2. Création de bases, gestion des droits, exports

          3. Eléments du langage de MYSQL

          4. Exemples de programmes de manipulation en MYSQL

          5. Interaction Web : PHP et MYSQL

          6. Exercices corrigés

 

                    Un mini-tuteur PHP est disponible ici pour la partie interface base de données et Web.

                    Sur les aspects conceptuels des bases de données,
                    on pourra consulter notre présentation Pluripass-BD-S3.

 

1.  Présentation de SQL et de MYSQL

MySql est un logiciel gestionnaire de bases de données qui implémente le langage abstrait SQL. Comme Sql, il se compose d'un LDD (langage de définition de données et de droits) ainsi qu'un LR (langage de requêtes) et d'un LMD (langage de manipulation des données).

Moins complet que PostgreSql ou Oracle, il est gratuit et livré en standard avec le serveur Apache et l'interpréteur Php dans les distributions EasyPHP, Wamp, Xampp. On lui préfère souvent Sqlite3 dans la phase de mise au point en développement Web parce que Sqlite ne requiert pas de mot de passe et met toutes les données dans un seul fichier facilement déplaçable.

Le concepteur de MySQL a ensuite créé MariaDB dont le nom est aussi lié à ses filles :

       non su

Une base de données relationnelle (c'est la base qui est relationnelle, pas les données, donc pas de S à "relationnelle") regroupe plusieurs tables de données. Par exemple pour une application classique dont la base de données est nommée GESTION, les tables pourront s'appeler CLIENTS, FOURNISSEURS, ARTICLES et COMMANDES mais nous utiliserons plus volontiers un exemple plus court avec deux tables ARTISTES et FILMS décrites ici et affichées .

Une table ressemble à un tableau écrit sur une feuille de papier avec des enregistrements et des champs qui sont à peu près l'équivalent des lignes et des colonnes. A peu près signifie que l'analogie s'arrête à la vision à un instant donné de l'affichage : en relationnel, les colonnes n'ont pas de numéro, les lignes non plus. Parler en relationnel de la colonne 5 ou des 10 premières lignes n'a donc aucun sens. Par contre, parler de la colonne nommée AGE ou SALAIRE a un sens, de même que parler des 5 premières lignes pour les lignes triées par ordre alphabétique...

On suppose que le lecteur, la lectrice de ce cours ont quelques connaissances sur les bases de données et sur les systèmes d'information en général. Sinon, nous recommandons le cours de P. RIGAUX et l'ensemble du site Web correspondant qui s'adresse aux étudiants du CNAM, cycle A à l'adresse

       http://cortes.cnam.fr:8080/BDA/DOC/cbd.pdf   (ou copie locale)

On y trouve les connaissances minimales qu'il faut avoir sur le modèle "Entités/Associations", sur les schémas relationnels et l'algèbre relationnelle : union, projections, jointure[s] etc. (copie locale) ainsi que sur les SGBDR (en anglais RDBMS)... On pourra aussi parcourir notre cours introduction aux bases de données relationnelles.

Ce texte ne présente que le coté "technique" de MYSQL. En particulier, aucune réflexion préalable aux tables et aux bases n'est présentée ici. Un cours de CONCEPTION des bases de données doit être utilisé pour cela, pour savoir conceptualiser, modéliser afin de définir les flux, les schémas conceptuels (MCD, MCT), pour définir les clés primaires, les relations etc. Ne pas avoir de champ HANDICAP pour savoir si une personne est handicapée rend IMPOSSIBLE la réponse à la question "Votre entreprise respecte-t-elle le quota légal de personnes handicapées ?". Ce n'est pas SQL qui est en cause mais bien la conception de la base : si l'information n'est pas là, SQL ne peut rien faire...

La conception d'une base n'est jamais simple et peut être fastidieuse. A titre d'exemple voici la définition d'une de nos bases du CHU, en image, via MySqlWorkbench :

modèle conceptuel

MYSQL est disponible sous Windows et sous Unix. Le site officiel est http://www.mysql.com et la version utilisée pour ce tuteur est 3.22.29.

Une fois le logiciel MYSQL installé et configuré et avec des droits utilisateurs corrects, on peut l'utiliser soit en ligne de commande (en interactif ou par programme) soit par l'intermédiaire d'une API (interface de programmation) avec des langages comme perl, php...

Pour utiliser MYSQL en interactif, on tape en ligne de commande


    mysql NOM_DE_BASE

et on quitte la session MYSQL en tapant


   QUIT ;

En mode non interactif, si on met les instructions dans un fichier, on peut exécuter le programme correspondant par


    mysql NOM_DE_BASE < NOM_DU_FICHIER

Au lieu d'afficher les résultats à l'écran, il est possible de les rediriger dans un fichie de sortie, suivant la syntaxe


    mysql NOM_DE_BASE < NOM_DU_FICHIER > NOM_DE_SORTIE

Il est à noter que chaque instruction MYSQL peut s'étendre sur plusieurs lignes mais qu'elle doit se terminer par un point-virgule.

Il y a de nombreuses options pour exécuter la commande mysql en ligne de commande afin de choisir la base, de gérer l'affichage etc. En particulier si on veut utiliser le serveur sirius/forge/janus à l'université avec le mot de passe anonymous pour l'utilisateur anonymous et la base test il faut écrire


    mysql --host=localhost --user=anonymous --password=anonymous

Sur le rapport entre XML et les bases de données, on pourra lire les documents xmlBD, XMLDBLinks et enfin Mapping DTDs to Databases car il est relativement naturel (mais parfois pas très optimal) de convertir des tables d'un schéma relationnel en balises...

2.  Création de bases, gestion des droits, exports

C'est en principe le responsable de la base de données -- qui n'est pas forcément le responsable système (ou "root" sous Linux) -- qui crée une base, par exemple avec la commande mysqladmin. Les droits peuvent ensuite être transmis par l'instruction GRANT. Par exemple, la création de la base tuteur par le responsable système se fait avec


  mysqladmin create tuteur ;

ensuite, ce même responsable peut exécuter en ligne


  mysql tuteur -e "GRANT ALL PRIVILEGES ON tuteur.* TO gh@localhost ;"

et l'utilisateur gh peut alors localement faire tout ce qu'il veut avec la base.

Les droits gérés par GRANT sont


  ALL PRIVILEGES, ALTER, CREATE, DELETE, DROP, FILE, INDEX, INSERT,
  PROCESS, REFERENCES, RELOAD, SELECT, SHUTDOWN, UPDATE, USAGE

Signalons que si l'instruction GRANT se termine par


  WITH GRANT OPTION ;

l'utilisateur désigné peut à son tour transmettre des droits.

Il y a beaucoup d'options de configuration et d'utilisation pour MySQL, accessibles via


  mysql --help

Le contenu de cette aide est ici.

Pour importer et exporter des données MySQL, on dispose en général de deux techniques : soit utiliser des instructions SQL ce qui permet de "rejouer" le code d'insertion ou d'exportation, soit passer par des fichiers-textes selon différents formats en profitant de ce que l'on nomme la redirection des entrées et des sorties en ligne de commandes. Ainsi la commande MySQL nommée mysqldump génère tout le code MySQL nécessaire à recréer toute une table. Voici sa syntaxe de base :


     Usage: mysqldump [OPTIONS] database [tables]
     OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
     OR     mysqldump [OPTIONS] --all-databases [OPTIONS]
     For more options, use mysqldump --help

On trouvera ici les détails des options de cette commande, détails obtenus via mysqldump --help.

Ainsi, pour sauvegarder toute la base de données LEAPdb, on peut utiliser le code


     mysqldump --host=localhost --user=***** --password=******* LEA >  dumpLEA.txt

à condition de disposer des droits suffisants, bien sûr.

On trouvera dans le fichier dumpLEA.txt le résultat de cette commande (taille du fichier : environ 5 Mo).

Comme le montrent les options de la commande mysql obtenues via mysql --help et mises dans le fichier mysql_help.txt via mysql --help > mysql_help.txt, MySQL dispose de nombreuses options de sorties, dont les formats CSV, HTML et XML sachant que par défaut les valeurs des champs sont séparés par le caractère de tabulation \t, ce qu'Excel et assimilés savent gérer.

3.  Eléments du langage de MYSQL

Un commentaire est une instruction non exécutable qui commence par un dièse. Si lors de l'appel de MYSQL, on ne précise pas le nom de la base à utiliser, la première instruction exécutable d'une session ou d'un programme MYSQL doit être


   USE Nom_Base ;

afin de choisir la base (et donc les tables associées).

L'instruction SELECT permet d'afficher des valeurs et d'extraire des données des bases. Par exemple


   SELECT VERSION() ; # affiche le numéro de version courante

   SELECT COUNT(*) FROM Nom_Table ; # indique le nombre d'enregistrements dans la table.

L'instruction SHOW affiche de nombreux renseignements concernant les base et les tables. Par exemple


   SHOW DATABASES ;  # donne la liste de toutes les bases.

   SHOW VARIABLES ;  # donne la liste et la valeur de toutes les variables système de configuration.

   SHOW STATUS ;     # décrit l'état de l'ensemble des paramètres de MYSQL.

   SHOW TABLES ;     # donne la liste de toutes les tables de la base en cours.

L'instruction DESCRIBE donne des informations sur une table particulière. Par exemple


   USE  Test ;
   DESCRIBE Tuteur ;

décrit tous les champs (ou "colonnes") de la table Tuteur pour la base Test alors que


   DESCRIBE Tuteur Qt ;

ne décrit que le champ Qt de cette table.

La création d'une table se fait avec l'instruction CREATE suivi du mot table et du nom de la table. On indique ensuite entre parenthèses le nom et le type des champs en séparant les champs par des virgules. Par exemple :


   CREATE TABLE fournisseurs ( code INT, nom CHAR ) ;

Les types de champs possibles sont


   INT, TINYINT, SMALLINT, MEDIUMINT, BIGINT,
   FLOAT, DOUBLE, DECIMAL,
   CHAR, VARCHAR, TEXT, TINYTEXT, MEDIUMTEXT, LONGTEXT,
   ENUM, SET.

Une fois la table créée, il est possible de modifier la structure avec l'instruction ALTER, comme par exemple


   ALTER TABLE fournisseurs ADD prenom char, ADD ref int ;
   ALTER TABLE sprots       DROP COLUMN notest ;

Les spécifications possibles pour ALTER sont


   ADD, ALTER, CHANGE, MODIFY, DROP, RENAME.

Pour détruire une table, on utilise DROP, comme par exemple


   DROP TABLE fournisseurs ;

Pour ajouter des données, on utilise INSERT, REPLACE, UPDATE et SET. L'instruction INSERT crée des données pour la première fois alors que REPLACE permet de modifier des valeurs déjà existantes. En cas d'index non nul, il n'est pas possible d'insérer deux fois la même valeur.

Exemples d'INSERT :


   INSERT INTO fournisseurs VALUES (10,"peper","jean",12) ;
   INSERT INTO fournisseurs (nom) VALUES  ("memer") ;
   INSERT INTO fournisseurs  (code,ref) VALUES  (100,200) ;
   INSERT INTO fournisseurs  (code,ref) VALUES  (100,code+1000) ;

Pour détruire des lignes on utilise DELETE, les conditions de suppression étant données dans le WHERE. Par exemple :

   DELETE FROM fournisseurs WHERE ref<100 ;

et pour tout détruire, il suffit de ne donner aucune condition, comme

   DELETE FROM fournisseurs  ;

L'extraction avec SELECT se fait selon la syntaxe générale

 SELECT expression INTO
                   FROM
                   WHERE
                   GROUP BY
                   HAVING
                   ORDER BY
                   LIMIT

On trouvera dans les programmes qui suivent de nombreux exemples de SELECT (une description plus complète est ici). Pour les fonctions sur groupes, un lien possible est group-by-functions. Il y a d'autre part des "fonctions de choix" (liens if et case). En voici un exemple d'utilisation :

 

          

     USE DBDB ;     
          
     SELECT CONCAT(pr_pdb_id , ch_name) AS nomProt ,     
            LENGTH(ch_fasta) AS longueur ,     
            pr_nbr_intra+pr_nbr_inter AS nbp ,     
            pr_nbr_intra AS nbintra ,     

            pr_nbr_inter AS nbinter ,     
            IF (pr_nbr_intra+pr_nbr_inter>0,"AVEC","SANS") AS pont ,     
            CASE     
              WHEN pr_nbr_intra=0 AND pr_nbr_inter=0 THEN "ACUCUN"     
              WHEN pr_nbr_intra=0 AND pr_nbr_inter>0 THEN "INTER_SEUL"     

              WHEN pr_nbr_intra>0 AND pr_nbr_inter=0 THEN "INTRA_SEUL"     
              WHEN pr_nbr_intra>0 AND pr_nbr_inter>0 THEN "INTER_ET_INTRA"     
            END AS naturePont     
            FROM dbdbprot a , dbdbchain b     
            WHERE a.pr_id = b.ch_pr_id  ;     

          
          
          

Signalons pour terminer cette section que l'insertion "massive" de données peut se faire avec la commande externe mysqlimport ou par la commande MYSQL LOAD DATA ... INFILE .

4.  Exemple de programmes de manipulation en MYSQL

Il y a 12 programmes puis une partie questions/réponses sur les tables artistes et films. Vous pouvez sans doute tester les commandes MySQL proposées via la page Web nommée  executeMysql .

Le programme 1 montre les instructions use, show, describe.

Le programme 2 reprend show.

La création d'une table correspond au programme 3 et on vient afficher la structure de la table nouvellement créée par le programme 4, que l'on modifie par le programme 5.

Quant au programme 6, il assure l'insertion de valeurs dans la table, valeurs que l'on affiche et compte par le programme 7.

Nous ajoutons une deuxième table reliée à la première avec des valeurs dans le programme 8 de façon à pouvoir, dans le programme 9 introduire la qualification totale, puis nous effectuons diverses jointures et des calculs plus techniques, comme la moyenne, l'écart-type sur des groupes d'enregistrements dans le programme 10.

Ensuite, le programme 11 utilise encore une autre base et montre des interrogations sur des champs-texte via des expressions régulières ainsi que divers tris et affichages.

Enfin le programme 12 montre comment calculer puis remplir des champs à partir d'autres champs.

Dans la partie suivante, des programmes en PHP montrent comment interfacer MYSQL dans des pages Web.


     Source du Programme 1  :
     -------------------------


      # p01.msql :  essayons d'utiliser la base tuteur

      USE tuteur ;

      # on exécute ce script par  mysql -f < p01.msql > resultats.p01

      USE  test     ;
      SHOW TABLES   ;
      DESCRIBE test.demo ;

      # rappel : la commande mysql nommé SHOW liste les tables

      # les commandes
      #     USE  XXX ;
      #     SHOW TABLES ;
      # donnent les tables de la base XXX ;

      # les commandes
      #     USE  XXX ;
      #     DESCRIBE YYY ;
      # décrivent la table YYY de la base XXX

      # fin de p01.msql



     Résultats  du Programme 1 :

     --------------
     SHOW TABLES
     --------------

     Tables in test
     bfone
     demo
     diremail
     eusers
     stages
     stagesM
     stgmass

     --------------
     DESCRIBE test.demo
     --------------

     Field     Type       Null         Key     Default     Extra
     nom       char(30)   YES          NULL
     prenom    char(30)   YES          NULL
     age       int(2)     YES          NULL
     naiss     int(4)     YES          NULL
     cine      int(1)     YES          NULL
     moto      int(1)     YES          NULL


     
     Source du Programme 2  :
     ------------------------


      # p02.msql

      USE test ;
      SHOW TABLES ;

      # si on est root, on peut ouvrir la table
      # user de la base mysql et gérer les
      # droits...

      #   mysql> USE mysql ;
      #   Database changed
      #   mysql> SHOW TABLES ;
      #   +-----------------+
      #   | Tables in mysql |
      #   +-----------------+
      #   | db              |
      #   | func            |
      #   | host            |
      #   | user            |
      #   +-----------------+
      #   4 rows in set (0.00 sec)
      #
      #   mysql> DESCRIBE user ;
      #   +---------------+----------+------+-----+---------+-------+
      #   | Field         | Type     | Null | Key | Default | Extra |
      #   +---------------+----------+------+-----+---------+-------+
      #   | Host          | char(60) |      | PRI |         |       |
      #   | User          | char(16) |      | PRI |         |       |
      #   | Password      | char(16) |      |     |         |       |
      #   | Select_priv   | char(1)  |      |     | N       |       |
      #   | Insert_priv   | char(1)  |      |     | N       |       |
      #   | Update_priv   | char(1)  |      |     | N       |       |
      #   | Delete_priv   | char(1)  |      |     | N       |       |
      #   | Create_priv   | char(1)  |      |     | N       |       |
      #   | Drop_priv     | char(1)  |      |     | N       |       |
      #   | Reload_priv   | char(1)  |      |     | N       |       |
      #   | Shutdown_priv | char(1)  |      |     | N       |       |
      #   | Process_priv  | char(1)  |      |     | N       |       |
      #   | File_priv     | char(1)  |      |     | N       |       |
      #   +---------------+----------+------+-----+---------+-------+
      #
      #   13 rows in set (0.00 sec)
      #
      #
      #   mysql> DESCRIBE host ;
      #   +-------------+----------+------+-----+---------+-------+
      #   | Field       | Type     | Null | Key | Default | Extra |
      #   +-------------+----------+------+-----+---------+-------+
      #   | Host        | char(60) |      | PRI |         |       |
      #   | Db          | char(32) |      | PRI |         |       |
      #   | Select_priv | char(1)  |      |     | N       |       |
      #   | Insert_priv | char(1)  |      |     | N       |       |
      #   | Update_priv | char(1)  |      |     | N       |       |
      #   | Delete_priv | char(1)  |      |     | N       |       |
      #   | Create_priv | char(1)  |      |     | N       |       |
      #   | Drop_priv   | char(1)  |      |     | N       |       |
      #   +-------------+----------+------+-----+---------+-------+
      #   8 rows in set (0.00 sec)

      # fin de p02.msql



     Résultats  du Programme 2 :

     --------------
     SHOW TABLES
     --------------

     Tables in test
     bfone
     demo
     diremail
     eusers
     stages
     stagesM
     stgmass


     Source du Programme 3  :
     --------------------------


      # -- p03.msql

      # on peut utiliser ce programme par mysql < p03.msql
      # ou, pour plus de detail par mysql -v < p03.msql

      # créons une nouvelle table

      USE test ;
      CREATE TABLE tuteur ( usr CHAR(2) NOT NULL, qt INT(4) )  ;

      # si on relance le programme une seconde fois, on a le message
      #    ERROR 1050 at line 6: Table 'tuteur' already exists

      # pour détruire la table
      #    drop   table tuteur ;

      # on peut écrire en ligne de commande ou en script
      #    mysql test -e "drop table tuteur " ;

      # -- fin de p03.msql



     Résultats  du Programme 3 : (aucun !)

     --------------
     CREATE TABLE tuteur ( usr CHAR(2) NOT NULL, qt INT(4) )
     --------------


     Source du Programme 4  :
     ------------------------

     # -- p04.sql

     # demandons la structure de la table tuteur dans la base test

     USE test ;
     DESCRIBE tuteur ;

     # on obtient :
     #
     #   +-------+---------+------+-----+---------+-------+
     #   | Field | Type    | Null | Key | Default | Extra |
     #   +-------+---------+------+-----+---------+-------+
     #   | qt    | int(4)  | YES  |     | NULL    |       |
     #   | usr   | char(2) |      |     |         |       |
     #   +-------+---------+------+-----+---------+-------+
     #   2 rows in set (0.00 sec)# fin de p04.sql
     #

     # -- fin de p04.msql



     Résultats  du Programme 4 :

     --------------
     DESCRIBE tuteur
     --------------

     Field     Type      Null          Key     Default     Extra
     usr       char(2)
     qt        int(4)     YES          NULL


     Source du Programme 5  :
     -------------------------


     # -- p05.msql

     # changeons la structure de la table tuteur

     USE test ;
     ALTER TABLE tuteur DROP usr, ADD user CHAR(2) NOT NULL ;

     # -- fin de p05.msql



     Résultats  du Programme 5 :

     --------------
     ALTER TABLE tuteur DROP usr, ADD user CHAR(2) NOT NULL
     --------------


     Source du Programme 6  :
     --------------------------


     # -- p06.msql

     # ajoutons des valeurs à la main dans la table tuteur
     # de la base test (champs qt et user)

     USE test ;
     INSERT INTO tuteur VALUES (1,'GH') ;
     INSERT INTO tuteur VALUES (2,'GG') ;
     INSERT INTO tuteur VALUES (3,'HU') ;
     INSERT INTO tuteur VALUES (4,'GH') ;
     INSERT INTO tuteur VALUES (5,'GH') ;
     INSERT INTO tuteur VALUES (3,'AA') ;
     INSERT INTO tuteur VALUES (5,'GH') ;
     INSERT INTO tuteur VALUES (8,'GG') ;
     INSERT INTO tuteur VALUES (7,'HU') ;
     INSERT INTO tuteur VALUES (2,'GH') ;
     INSERT INTO tuteur VALUES (5,'GH') ;
     INSERT INTO tuteur VALUES (9,'AA') ;


     # -- fin de p06.msql




     Résultats  du Programme 6 :

     --------------
     INSERT INTO tuteur VALUES (1,'GH')
     --------------
     INSERT INTO tuteur VALUES (2,'GG')
     --------------
     INSERT INTO tuteur VALUES (3,'HU')
     --------------
     INSERT INTO tuteur VALUES (4,'GH')
     --------------
     INSERT INTO tuteur VALUES (5,'GH')
     --------------
     ...



     Source du Programme 7  :
     ------------------------

     # -- p07.msql

     USE test ;

     # demandons à voir tous les enregistrements

     SELECT * FROM tuteur ;

     # en cas d'erreur, on vide la table par
     # mysql test -e " delete from tuteur ; "

     # demandons le nombre d'enregistrements...

     SELECT COUNT(*) FROM  tuteur ;

     # les différents utilisateurs

     SELECT DISTINCT(user) FROM tuteur ;

     # divers affichages

     SELECT DISTINCT(qt) FROM tuteur ORDER BY qt ;

     SELECT user,qt FROM tuteur ORDER BY user ;
     SELECT qt,user FROM tuteur ORDER BY user ;
     SELECT user,qt,' soit ',qt*3.25 FROM tuteur ORDER BY user ;

     # -- fin de p07.msql



     Résultats  du Programme 7 :

     --------------
     SELECT * from tuteur
     --------------

     qt    user
     1     GH
     2     GG
     3     HU
     4     GH
     5     GH
     3     AA
     5     GH
     8     GG
     7     HU
     2     GH
     5     GH
     9     AA

     --------------
     SELECT COUNT(*) FROM  tuteur
     --------------

     count(*)
     12

     --------------
     SELECT DISTINCT(user) FROM tuteur
     --------------

     user
     AA
     GG
     GH
     HU

     --------------
     SELECT DISTINCT(qt) FROM tuteur ORDER BY qt
     --------------

     qt
     1
     2
     3
     4
     5
     7
     8
     9

     --------------
     SELECT user,qt FROM tuteur ORDER BY user
     --------------

     user   qt
     AA     3
     AA     9
     GG     2
     GG     8
     GH     1
     GH     4
     GH     5
     GH     5
     GH     2
     GH     5
     HU     3
     HU     7

     --------------
     SELECT qt,user FROM tuteur ORDER BY user
     --------------

     qt    user
     3     AA
     9     AA
     2     GG
     8     GG
     1     GH
     4     GH
     5     GH
     5     GH
     2     GH
     5     GH
     3     HU
     7     HU

     --------------
     SELECT user,qt,' soit ',qt*3.25 FROM tuteur ORDER BY user
     --------------

     user   qt     soit      qt*3.25
     AA     3      soit      9.75
     AA     9      soit      29.25
     GG     2      soit      6.50
     GG     8      soit      26.00
     GH     1      soit      3.25
     GH     4      soit      13.00
     GH     5      soit      16.25
     GH     5      soit      16.25
     GH     2      soit      6.50
     GH     5      soit      16.25
     HU     3      soit      9.75
     HU     7      soit      22.75


     Source du Programme 8  :
     ------------------------


     # -- p08.msql

     # rajoutons une table decode des noms correspondant
     # mis dans le champ nom ; les initiales dans le champ usr
     # correspondent aux initiales mises dans le champ user
     # de la table tuteur

     USE test ;

     CREATE TABLE decode ( usr CHAR(2) NOT NULL, nom CHAR(40) )  ;

     INSERT INTO decode VALUES ('AA','Andrée Tarkowsky') ;
     INSERT INTO decode VALUES ('GG','Gérard Manvussa') ;
     INSERT INTO decode VALUES ('GH','Gilles Hunault') ;
     INSERT INTO decode VALUES ('HU','Hubert Hubert') ;

     SELECT * FROM decode ;

     # -- fin de p08.msql



     Résultats  du Programme 8 :

     --------------
     CREATE TABLE decode ( usr CHAR(2) NOT NULL, nom CHAR(40) )
     --------------
     INSERT INTO decode VALUES ('AA','Andrée Tarkowsky')
     --------------
     INSERT INTO decode VALUES ('GG','Gérard Manvussa')
     --------------
     INSERT INTO decode VALUES ('GH','Gilles Hunault')
     --------------
     INSERT INTO decode VALUES ('HU','Hubert Hubert')
     --------------
     SELECT * FROM decode
     --------------

     usr    nom
     AA     Andrée Tarkowsky
     GG     Gérard Manvussa
     GH     Gilles Hunault
     HU     Hubert Hubert


     
     Source du Programme 9  :
     ------------------------


     # -- p09.msql

     USE test ;

     # utilisons la qualification totale

     SELECT DISTINCT(test.tuteur.user) FROM tuteur ;

     # ceci est une erreur :
     # SELECT usr, DISTINCT(test.decode.nom) FROM decode ;

     # mais pas :

     SELECT DISTINCT(usr),test.decode.nom FROM decode ;

     # plus lisible

     SELECT DISTINCT(usr),' est le code de : ',test.decode.nom FROM decode ;

     # autre possibilité

     SELECT ' code : ',usr,' utilisateur : ',test.decode.nom FROM decode ;

     # -- fin de p09.msql



     Résultats  du Programme 9 :

     --------------
     SELECT DISTINCT(test.tuteur.user) FROM tuteur
     --------------

     user
     AA
     GG
     GH
     HU

     --------------
     SELECT DISTINCT(usr),test.decode.nom FROM decode
     --------------

     usr    nom
     AA     Andrée Tarkowsky
     GG     Gérard Manvussa
     GH     Gilles Hunault
     HU     Hubert Hubert

     --------------
     SELECT DISTINCT(usr),' est le code de : ',test.decode.nom FROM decode
     --------------

     usr     est le code de :      nom
     AA      est le code de :      Andrée Tarkowsky
     GG      est le code de :      Gérard Manvussa
     GH      est le code de :      Gilles Hunault
     HU      est le code de :      Hubert Hubert

     --------------
     SELECT ' code : ',usr,' utilisateur : ',test.decode.nom FROM decode
     --------------

      code :      usr     utilisateur :      nom
      code :      AA      utilisateur :      Andrée Tarkowsky
      code :      GG      utilisateur :      Gérard Manvussa
      code :      GH      utilisateur :      Gilles Hunault
      code :      HU      utilisateur :      Hubert Hubert

    
    Source du Programme 10 :
     ------------------------


     # -- p10.msql

     # lions les deux tables de la base

     USE test ;

     SELECT decode.nom,tuteur.qt FROM decode,tuteur
            WHERE tuteur.user=decode.usr ;

     # comptage simple

     SELECT decode.nom, COUNT(tuteur.qt) FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom ;

     # recherche du minimum

     SELECT decode.nom, MIN(tuteur.qt) FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom  ;

     # recherche du minimum en tant qu'alias et tri sur ce minimum

     SELECT MIN(tuteur.qt) AS minQt, decode.nom FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom ORDER BY minQt ;

     # valeur moyenne de qt

     SELECT nom, AVG(qt) AS moyQt FROM decode,tuteur
            WHERE user=usr GROUP BY nom ORDER BY moyQt ;

     # valeur moyenne de qt*15 avec cadrage

     SELECT LEFT(CONCAT(nom,"................."),24), AVG(qt*15.0) AS moyQt FROM decode,tuteur
            WHERE user=usr GROUP BY nom ORDER BY moyQt ;

     # moyenne, écart-type de qt avec cadrage et divers  tris

     SELECT LEFT(CONCAT(UPPER(nom),"           ..........."),35), AVG(qt) AS moyqt,
            STD(qt) FROM decode,tuteur
            WHERE user=usr GROUP BY user ORDER BY moyQt DESC ;

     SELECT LEFT(CONCAT(UPPER(nom),"           ..........."),35),
            AVG(qt), STD(qt) AS stdQt
            FROM decode,tuteur
            WHERE user=usr group by user ORDER BY stdQt DESC ;

     SELECT LEFT(CONCAT(UPPER(nom),"           ..........."),35), AVG(qt),
            STD(qt), STD(qt)*100/AVG(QT) AS valCv FROM decode,tuteur
            WHERE user=usr GROUP BY user ORDER BY valCv desc ;

     # -- fin de p10.msql



     Résultats  du Programme 10 :

     --------------
     SELECT decode.nom,tuteur.qt FROM decode,tuteur
            WHERE tuteur.user=decode.usr
     --------------

     nom                 qt
     Gilles Hunault      1
     Gérard Manvussa     2
     Hubert Hubert       3
     Gilles Hunault      4
     Gilles Hunault      5
     Andrée Tarkowsky    3
     Gilles Hunault      5
     Gérard Manvussa     8
     Hubert Hubert       7
     Gilles Hunault      2
     Gilles Hunault      5
     Andrée Tarkowsky    9

     --------------
     SELECT decode.nom, COUNT(tuteur.qt) FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom
     --------------

     nom                  count(tuteur.qt)
     Andrée Tarkowsky     2
     Gérard Manvussa      2
     Gilles Hunault       6
     Hubert Hubert        2

     --------------
     SELECT decode.nom,MIN(tuteur.qt) FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom
     --------------

     nom                  MIN(tuteur.qt)
     Andrée Tarkowsky     3
     Gérard Manvussa      2
     Gilles Hunault       1
     Hubert Hubert        3

     --------------
     SELECT MIN(tuteur.qt) AS minQt, decode.nom FROM decode,tuteur
            WHERE tuteur.user=decode.usr GROUP BY decode.nom ORDER BY minQt
     --------------

     minQt nom
     1     Gilles Hunault
     2     Gérard Manvussa
     3     Hubert Hubert
     3     Andrée Tarkowsky

     --------------
     SELECT nom, AVG(qt) AS moyQt FROM decode,tuteur
            WHERE user=usr GROUP BY user ORDER BY moyQt
     --------------

     nom                  moyQt
     Gilles Hunault       3.6667
     Gérard Manvussa      5.0000
     Hubert Hubert        5.0000
     Andrée Tarkowsky     6.0000

     --------------
     SELECT LEFT(CONCAT(nom,"................."),24),
            AVG(qt*15.0) AS moyQt FROM decode,tuteur
            WHERE user=usr GROUP BY user ORDER BY moyQt
     --------------

     LEFT(CONCAT(nom,"................."),24)     moyQt
     Gilles Hunault..........     55.00000
     Gérard Manvussa.........     75.00000
     Hubert Hubert...........     75.00000
     Andrée Tarkowsky........     90.00000

     --------------
     SELECT LEFT(CONCAT(UPPER(nom),"           ..........."),35),
            AVG(qt) AS moyQt,STD(qt) FROM decode,tuteur
            WHERE user=usr GROUP BY user ORDER BY moyQt DESC
     --------------

     
     Source du Programme 11 :
     ------------------------


     # -- p11.msql

     # on utilise la table diremail de la base test

     USE test ;

     # la structure de diremail est

     #   mysql> DESCRIBE diremail ;
     #   +--------+----------+------+-----+---------+-------+
     #   | Field  | Type     | Null | Key | Default | Extra |
     #   +--------+----------+------+-----+---------+-------+
     #   | jourR  | int(2)   | YES  |     | NULL    |       |
     #   | moisR  | int(2)   | YES  |     | NULL    |       |
     #   | anneR  | int(4)   | YES  |     | NULL    |       |
     #   | nomvu  | char(80) | YES  |     | NULL    |       |
     #   | pnmvu  | char(30) | YES  |     | NULL    |       |
     #   | email  | char(80) |      | PRI |         |       |
     #   | source | char(20) | YES  |     | NULL    |       |
     #   +--------+----------+------+-----+---------+-------+
     #   7 rows in set (0.00 sec)
     #

     # nombre d'enregistrements

     SELECT COUNT(email) FROM diremail ;

     # les années

     SELECT DISTINCT(anneR) FROM diremail ORDER BY anneR ;

     # les mois par année

     # INVALIDE : SELECT DISTINCT(moisR),DISTINCT(anneR) FROM diremail ORDER BY anneR ;
     SELECT DISTINCT(moisR),anneR FROM diremail ORDER BY anneR desc,moisR desc;

     # le détail des jours

     SELECT DISTINCT(jourR),moisR,anneR FROM diremail
            ORDER BY anneR desc,moisR desc, jourR DESC ;

     # un peu de comptage

     SELECT anneR,moisR FROM diremail GROUP BY moisR,anneR
            ORDER BY anneR desc,moisR DESC ;

     SELECT anneR,moisR,COUNT(email) FROM diremail GROUP BY moisR,anneR
            ORDER BY anneR desc,moisR DESC ;

     SELECT anneR,moisR,jourR,COUNT(email) FROM diremail GROUP BY jourR,moisR,anneR
            ORDER BY anneR desc,moisR desc,jourR DESC ;

     # comptons les emails par abonnement

     SELECT COUNT(*) FROM diremail ;
     SELECT COUNT(*) FROM diremail WHERE email LIKE "%wanadoo.fr" ;
     SELECT COUNT(*) FROM diremail WHERE email LIKE "%yahoo.fr" ;
     SELECT COUNT(*) FROM diremail
            WHERE not(email LIKE "%yahoo.fr"  OR email LIKE "%wanadoo.fr") ;

     # puis cherchons des noms avec LIKE et REGEXP

     SELECT * FROM diremail WHERE nomvu LIKE   "aar%" ;
     SELECT * FROM diremail WHERE nomvu LIKE   "%caa" ;
     SELECT * FROM diremail WHERE nomvu REGEXP "AA.*R" ;

     # enfin, calculons des moyennes

     CREATE TABLE TmpMoy ( an int(4), mois int(2), jour int(2), nb int ) ;

     INSERT into TmpMoy
            SELECT anneR,moisR,jourR,COUNT(email)
            FROM diremail GROUP BY jourR,moisR,anneR
            ORDER BY anneR desc,moisR desc,jourR DESC ;

     SELECT an,mois,COUNT(nb) FROM TmpMoy
            GROUP BY mois,an ORDER BY an desc,mois DESC  ;
     SELECT an,mois,AVG(nb)   FROM TmpMoy
            GROUP BY mois,an ORDER BY an desc,mois DESC  ;

     DROP TABLE TmpMoy ;

     # -- fin de p11.msql



     Résultats  du Programme 11 :

     COUNT(email)
     5476

     --------------
     SELECT DISTINCT(anneR) FROM diremail ORDER BY anneR
     --------------

     anneR
     1999
     2000

     --------------
     SELECT DISTINCT(moisR),anneR FROM diremail ORDER BY anneR desc,moisR DESC
     --------------

     moisR  anneR
     10     2000
      9     2000
     10     1999
      9     1999
      8     1999

     --------------
     SELECT DISTINCT(jourR),moisR,anneR FROM diremail
            ORDER BY anneR desc,moisR desc, jourR DESC
     --------------

     jourR  moisR  anneR
     21     10     2000
     21      9     2000
     21     10     1999
     20     10     1999
     19     10     1999
     18     10     1999
     15     10     1999
     28      9     1999
     19      9     1999
     31      8     1999
     20      8     1999

     --------------
     SELECT anneR,moisR FROM diremail GROUP BY moisR,anneR
            ORDER BY anneR desc,moisR DESC
     --------------

     anneR    moisR
     2000     10
     2000      9
     1999     10
     1999      9
     1999      8

     --------------
     SELECT anneR,moisR,COUNT(email) FROM diremail
            GROUP BY moisR,anneR ORDER BY anneR desc,moisR DESC
     --------------

     anneR    moisR  COUNT(email)
     2000     10     1
     2000      9     1
     1999     10     4122
     1999      9     25
     1999      8     1327

     --------------
     SELECT anneR,moisR,jourR,COUNT(email) FROM diremail
            GROUP BY jourR,moisR,anneR ORDER BY anneR desc,moisR desc,jourR DESC
     --------------

     anneR    moisR  jourR  COUNT(email)
     2000     10     21     1
     2000      9     21     1
     1999     10     21     1400
     1999     10     20     1554
     1999     10     19     592
     1999     10     18     25
     1999     10     15     551
     1999      9     28     13
     1999      9     19     12
     1999      8     31     1323
     1999      8     20     4

     --------------
     SELECT COUNT(*) FROM diremail
     --------------

     COUNT(*)
     5476

     --------------
     SELECT COUNT(*) FROM diremail WHERE email LIKE "%wanadoo.fr"
     --------------

     COUNT(*)
     3080

     --------------
     SELECT COUNT(*) FROM diremail WHERE email LIKE "%yahoo.fr"
     --------------

     COUNT(*)
     1730

     --------------
     SELECT COUNT(*) FROM diremail
            WHERE NOT(email LIKE "%yahoo.fr"  OR email LIKE "%wanadoo.fr")
     --------------

     COUNT(*)
     666

     --------------
     SELECT * FROM diremail WHERE nomvu LIKE   "aar%"
     --------------

     jourR  moisR  anneR    nomvu     pnmvu     email                  source
     20     10     1999     AARID     Najim      n_aarid@yahoo.fr      YahooPS
     20     10     1999     AARIF     Bnimellal  bnimellal@yahoo.fr    YahooPS

     --------------
     SELECT * FROM diremail WHERE nomvu LIKE   "%caa"
     --------------

     jourR  moisR  anneR    nomvu           pnmvu       email               source
     15     10     1999     MINCHE AGNCAA   Christian   agncaa@wanadoo.fr   SwitchBoardPS

     --------------
     SELECT * FROM diremail WHERE nomvu REGEXP "AA.*R"
     --------------

     jourR  moisR  anneR    nomvu      pnmvu       email                     source
     20     10     1999     AZZAANKARA Hicham      copycat1980@yahoo.fr      YahooPS
     20     10     1999     AARID      Najim       n_aarid@yahoo.fr          YahooPS
     20     10     1999     AARIF      Bnimellal   bnimellal@yahoo.fr        EbayAdr
     21     10     1999     AJAAFAR    Mokhtar     image.service@wanadoo.fr  YahooPS

     --------------
     CREATE TABLE TmpMoy ( an INT(4), mois INT(2), jour INT(2), nb INT )
     --------------
     INSERT INTO TmpMoy
            SELECT anneR,moisR,jourR,COUNT(email)
            FROM diremail GROUP BY jourR,moisR,anneR
            ORDER BY anneR desc,moisR desc,jourR DESC
     --------------
     SELECT an,mois,COUNT(nb) FROM TmpMoy
            GROUP BY mois,an ORDER BY an desc,mois DESC
     --------------

     an      mois    COUNT(nb)
     2000     10     1
     2000      9     1
     1999     10     5
     1999      9     2
     1999      8     2

     --------------
     SELECT an,mois,AVG(nb) FROM TmpMoy
            GROUP BY mois,an ORDER BY an desc,mois DESC
     --------------

     an     mois     AVG(nb)
     2000     10       1.0000
     2000      9       1.0000
     1999     10     824.4000
     1999      9      12.5000
     1999      8     663.5000

     --------------
     DROP TABLE TmpMoy
     --------------


     
     Source du Programme 12 :
     ----------------------------


     # -- p12.msql

     # on rajoute le prix a payer dans le champ prix
     # avec un meme prix unitaire de 325000.17 F

     USE    test ;
     ALTER  TABLE  tuteur ADD prix float ;
     UPDATE tuteur SET prix=325000.17*qt ;
     SELECT * FROM tuteur ;

     # on reprend en prixAmi avec un prix unitaire de 100 F
     # et une remise pour GH

     ALTER  TABLE  tuteur ADD prixAmi float ;
     UPDATE tuteur SET prixAmi=IF(user="GH",90*qt,100*qt) ;
     SELECT * FROM tuteur ;

     # -- fin de p12.msql



     Résultats  du Programme 12 :

     --------------
     ALTER  TABLE  tuteur ADD prix float
     --------------
     UPDATE tuteur SET prix=325000.17*qt
     --------------
     SELECT * FROM tuteur
     --------------

     qt    user   prix
     1     GH      325000.16
     2     GG      650000.31
     3     HU      975000.50
     4     GH     1300000.62
     5     GH     1625000.88
     3     AA      975000.50
     5     GH     1625000.88
     8     GG     2600001.25
     7     HU     2275001.25
     2     GH      650000.31
     5     GH     1625000.88
     9     AA     2925001.50

     --------------
     ALTER  TABLE  tuteur ADD prixAmi float
     --------------
     UPDATE tuteur SET prixAmi=IF(user="GH",90*qt,100*qt)
     --------------
     SELECT * FROM tuteur
     --------------

     qt    user    prix          prixAmi
     1     GH      325000.16      90.00
     2     GG      650000.31     200.00
     3     HU      975000.50     300.00
     4     GH     1300000.62     360.00
     5     GH     1625000.88     450.00
     3     AA      975000.50     300.00
     5     GH     1625000.88     450.00
     8     GG     2600001.25     800.00
     7     HU     2275001.25     700.00
     2     GH      650000.31     180.00
     5     GH     1625000.88     450.00
     9     AA     2925001.50     900.00

Questions et réponses sur les tables ARTISTES et FILMS

Depuis 2018 cette partie questions et réponses est accessible sur la page artistes et films.

Un exemple plus complexe

Il est possible de demander à MySQL de stocker des résultats dans des variables (repérées par un symbole "@" en début de nom de variable), et même de numéroter les lignes de résultats des requêtes comme le montre le code suivant :


     ## un calcul un peu complexe en MySQL :

     # affichage des personnes qui fument et qui ronflent, de plus de soixante ans
     # et qui ont un poids inférieur à la moyenne moins 1,25 fois l'écart-type du poids général
     # affichage avec lignes numérotées ; critère de tri : matricule des personnes
     # données : table RONFLE, base STATDATA.

     SET @compteur = 0 ;
     SET @moy      = (SELECT AVG(poids) FROM ronfle ) ;
     SET @ect      = (SELECT STD(poids) FROM ronfle ) ;
     SET @liminf   = ( @moy - 1.25*@ect ) ;

     SELECT @compteur := @compteur + 1 AS "num",
            iden, age, poids, sexe, taille, alcool
            FROM  ronfle
            WHERE (ronfle=1) AND (taba=1) AND (age>60)
            AND   (poids < @liminf)
            ORDER BY iden
     ; # fin de select

Affichage :


        +------+-------+-----+-------+------+--------+--------+
        | num  | IDEN  | AGE | POIDS | SEXE | TAILLE | ALCOOL |
        +------+-------+-----+-------+------+--------+--------+
        |    1 | P0092 |  64 |    49 |    0 |    164 |      4 |
        |    2 | P0096 |  64 |    54 |    0 |    159 |      4 |
        +------+-------+-----+-------+------+--------+--------+

        2 rows in set (0.00 sec)

 

5.  Interaction Web : PHP et MYSQL

Nous terminons ce petit tuteur par quelques remarques sur PHP qui est un langage de programmation pour le web. Il interface de nombreux systèmes de bases de données pour le Web et en particulier MYSQL. Si vous ne connaissez PHP, un tuteur PHP est disponible ici.

Dans la mesure où depuis 2018 la version officielle de PHP est la version 7, il convient de passer par PDO pour faire dialoguer PHP avec MySQL. On pourra sans doute se contenter d'interfacer PHP avec SQLITE3 en développement car plus simple de mise en place avant d'interfacer PHP avec MySQL en test et en production.

La section section 4.3 de notre tuteur PHP fournit des exemples d'interfaçage entre PHP et SQL.

 

6.  Exercices corrigés

Pour tester vos connaissances en SQL et en MySql, vous pouvez essayer de répondre (dans cet ordre) aux questions suivantes. Si vous avez accès à nos serveurs, les tables sont dans la base statdata sur forge/janus.

1.  titanic  énoncé solution exécution
  (données sur les passagers du Titanic)
2.  elf   énoncé solution exécution
  (ELF : enquête linguistique sur la féminisation des noms de métiers)
3.  ronfle  énoncé solution exécution
  (données hospitalières pour des gens qui boivent, fument et ronflent)
4.  2tables  énoncé solution exécution
  (sessions de formation continue : cours et participants)
5.  4tables  énoncé solution exécution
  (articles, clients, fournisseurs et commandes)

Vous pouvez télécharger ici une archive zip qui contient les instructions MySql pour [re]générer les 9 tables des 5 exercices, soit avec la redirection de l'entrée, soit avec l'instruction source :


    # utilisation de source sous mysql

    $unix> mysql  --host=localhost --user=anonymous --password=anonymous

    mysql> use statdata ; # mais elle n'existe pas !
    mysql> create database statdata ;
    mysql> source elf_mysql_cr.txt  ;
    mysql> quit ;

    # utilisation de la redirection de l'entrée

    $unix> mysql  statdata --host=localhost --user=anonymous --password=anonymous < ronfle_mysql_cr.txt

Enfin, une interface Web pour tester du code sql est  ici 

Elle permet d'exécuter des requêtes sur le serveur forge de bases de données du département informatique de la faculté des sciences d'Angers.

 


 

Rappel de la Table des matières

          1. Présentation de MYSQL

          2. Création de bases, gestion des droits, exports

          3. Eléments du langage de MYSQL

          4. Exemple de programmes de manipulations en MYSQL

          5. Interaction Web : PHP et MYSQL

          6. Exercices corrigés

 

retour gH    Retour à la page principale de   (gH)