- Quelques rappels de vocabulaire
- base de données, table, champ (ou colonne), enregistrement (ou ligne)
- structure ou schéma relationnel d'une base
- clé primaire : un ou plusieurs champ déterminent complétement les valeurs des autres champs de la table
- clé externe : il s'agit d'un champ d'une table qui joue le rôle de clé primaire dans une autre table de la base
- Types de données et création d'une table
- numériques entiers : INTEGER (entiers sur 4 octets.), SMALLINT (2 octest), BIGINT (8),
- décimaux exacts : NUMERIC, DECIMAL (p,q): décimaux sur p chiffres dont q forment la partie décimale. Pour garder la
précision, l sont stocker sous forme de chaine
- FLOAT(p,q) .
- CHAR(n), VARCHAR(n) : chaine de caractères de longeur fixée ou variable (n<=255).
Comme il n'y a pas de type logique, on le simule par un CHAR(1) avec 2 valeurs
- DATE : date au format par défaut aaaaa-mm-jj (la fonction DATE_FORMAT pzermet des conversions)
- TIME: heure au format hh:mm:ss
- TIMESTAMP : date et heure sous forme du nb de secondes écoulées depuis le 1/1/1970
(date de création du monde selon UNIX ;-). Lors d'une insertion ou mise à jour une champ TIMESTAMP se met à jour à la
date courante
- ENUM et SET sont des extensions Mysql : valeur unique dans l'ensemble spécifié ou ens.de valeurs appartenant au type
- TEXT : texte de longueur qcq
Il est recommandé de placer sur les valeurs des champs les contraintes NOT NULL au moment de la création (donc éviter
la valeur NULL ou absence de valeur qui ne permet pas les comparaisons), ou de
placer des valeurs par défaut avec DEFAULT valeur ('' ou 0).
Bien sûr chaque table doit posséder une clé primaire simple ou composée, introduite par le mot-clé PRIMARY KEY.
Un exemple, à commenter :
CREATE TABLE b2i (
rne varchar(8) NOT NULL default '',
annee varchar(9) NOT NULL default '',
niv1 smallint(6) NOT NULL default '0',
niv2 smallint(6) NOT NULL default '0',
amelioration char(1) NOT NULL default 'N',
observation text,
PRIMARY KEY (rne,annee)
)
- Opérateurs logiques
Ils permettent de construire des expressions logiques, donnant des valeurs logiques vrai ou faux.
Divers cas :
- AND, OR, NOT : ils portent sur les conditions simples pour donner une condition composée :
- dans une condition simple exprimée sur des champs :
- comparaison de valeurs =, <, >,
- valeurs situées entre
BETWEEN ....AND....
- ou appartenant (ou non) à un ensemble
IN, NOT IN
- semblable à
LIKE
- existence
EXISTS
- Règle générale d'écriture des commandes
Toute commande SQL commence par un
mot-clé qui désigne l'opération à exécuter. On précise ensuite sur
quelles données cette opération doit s'exercer. Elle doit obligatoirement se terminer par ;
Exemple d'interrogation simple
SELECT numArticle, libellé, quantité // projection sur les colonnes indiquées,
FROM inventaire // de la table inventaire de la base de données courante,
WHERE Ville= "Paris" // sélection des lignes où le champ Ville a la valeur "Paris"
RDER BY quantite; // ordonné suivant les valeurs croissantes du champ quantité
- Syntaxe générale de la commande d'interrogation SELECT
SELECT [DISTINCT] liste_champs | * // projection
FROM liste_tables // produit catésien
[ WHERE condition // condition simple ou composée portant sur les attributs
[AND|OR ......] ] // sur une table (sélection) ou 2 (jointure)
[GROUP BY champ] // décrit le regroupement des lignes
[HAVING champ] // critères de sélection portant sur les groupes
[ORDER BY liste_champs]; // précise le tri (multi-critère)
- liste désigne une énumération dont le séparateur est la virgule
- l'ordre des clauses est impérative, la plupart sont facultatives
- les mots-clés sont écrits en majuscules, uniquement pour accroitre la lisibilité
- Expérimentez, expliquez chaque requête, et discutez de leur justesse
- Utilisation de quelques fonctions Mysql
Les fonctions permettent en général d'agir sur les valeurs extraites par l'exécution d'une commande.
Noter aussi qu'on peut introduire des chaines constantes.
SELECT 225*25 ;
SELECT version(), now(), curdate() as date, curtime() as heure ;
SELECT DATE_FORMAT(now(),'%d/%m/%Y') AS date ;
SELECT concat('Voici la date d\'aujourd\'hui :', DATE_FORMAT(now(),'%d/%m/%Y')) AS date ;
SELECT DATE_ADD(now(), INTERVAL -1 DAY); autre période second, minute,hour,month,year
SELECT substring('chaine', 1, 2) ; autres fonctions LENGTH
SELECT if(12 > 10, '12 est plus grand', '12 est plus petit');
Il peut etre utile de regrouper plusieurs informations et meme plusieurs champs. Par exemple sur la base établissments
SELECT * FROM etablissements WHERE left(CodePostal,2)='94' ORDER BY Ville;
SELECT concat(nom,' ', type,' ',ville) FROM etablissements ORDER BY nom;
- Il s'agit d'écrire et d'expérimenter des requêtes sur les bases test ou cdi
- directement avec l'utilitaire
mysql, en dialoguant en mode texte avec le serveur mysqld
- par l'intermédiaire de l'utilitaire
phpMyAdmin en accèdant au serveur mysqld par l'intermédiaire d'une
interface écrite en PHP
- ou mieux à l'aide des scripts interroger.php et reponse.php
- Il faut savoir que certaines instructions et concepts ne sont pas (encore) implémentés dans MySql (par exemple, les sous-requetes)
- Voici la structure de la base CDI
documents (id_document,titre, auteur, genre, editeur, disponible)
inscrits (id_inscrit, nom, prenom, classe)
prets (id_pret, id_inscrit #, id_document #, date_pret, date_retour, retour)
demandes (id_demande, id_inscrit #, id_document #)
- Interrogations simples sur une table
SELECT * FROM inscrits ;
SELECT count(*) FROM inscrits ;
SELECT count(*) AS nb FROM inscrits WHERE classe = '6a' ;
autres fonctions AVG (moyenne), MIN, MAX, SUM
" Quelle est la moyenne des valeurs d'un champ note dans une table carnet_notes ? "
SELECT AVG(note) as moyenne from carnet_notes ;
" Combien de documents disponibles sur leur total ?"
SELECT SUM(disponible) disponible, count(*) nombre FROM documents ;
SELECT auteur FROM documents ;
SELECT DISTINCT auteur FROM documents ;
SELECT titre, auteur FROM documents LIMIT 0,10 ;
SELECT titre, auteur FROM documents ORDER BY auteur ;
SELECT prenom, nom, classe FROM inscrits ORDER BY nom DESC LIMIT 0,10 ;
SELECT prenom, nom, classe FROM inscrits ORDER BY classe, nom, prenom ;
SELECT * FROM documents WHERE BINARY titre='ivanohé' ";
- Requêtes avec condition simple
Une condition simple est construite avec les opérateurs de comparaison usuels < > = != portant sur des valeurs de
champs. On dispose de quelques opérateurs spécifiques : LIKE et NOT LIKE
SELECT nom, prenom, classe FROM inscrits WHERE nom >= 'x' ;
SELECT DISTINCT titre, auteur FROM documents WHERE titre LIKE '%mis%' ;
SELECT titre, auteur FROM documents WHERE titre LIKE '% mis%' ;
SELECT auteur, titre FROM inscrits WHERE classe = '6a' ;
SELECT titre, auteur FROM documents WHERE titre LIKE '%mis%' ;
SELECT titre, auteur FROM documents WHERE titre LIKE '% mis%' ;
SELECT titre, auteur FROM documents WHERE titre LIKE '%mis%' AND auteur NOT LIKE '%hugo%' ;
- Requêtes avec condition composée
AND, OR, NOT portant sur les conditions simples (attention, AND étant prioritaire sur OR, il peut être nécessaire
de parenthéser)
SELECT nom,prenom,classe FROM inscrits WHERE (nom >='v' OR nom <'c') AND classe='6a' ;
SELECT titre, auteur FROM inscrits WHERE nom BETWEEN 'h' AND 'm' ;
Les opérateurs d'appartenance à une liste discrète ou à un intervalle "continu" permettent
d'abréger les conditions composées : [NOT] IN (liste_valeurs) et BETWEEN valeur1 AND valeur2.
SELECT nom,prenom,classe FROM inscrits WHERE classe IN ('6A','6c','6f');
- Approche notion de regroupement
"Quels sont les effectifs par classe des inscrits ?"
La fonction de comptage count() dans ce contexte s'applique à chaque ensemble résultant de la partition suivant la valeur
du champ classe
SELECT classe, count(*) as nombre
FROM inscrits
GROUP BY classe ;
"Quelles sont les classes dont l'effectif est limité à 24 élèves ?"
Une condition portant sur les enregistrements regroupés s'exprime avec la clause HAVING (et non WHERE)
SELECT classe, count(*) as nombre
FROM inscrits
GROUP BY classe
HAVING nombre <= 24;
- Jointures simples
SELECT count(*) FROM inscrits, documents ;
SELECT count(*) as nb, 225*25 FROM inscrits, documents WHERE classe='6a';
"Quels sont les documents actuellement empruntés ? ("actuellement" : tester le champ prets.retour=0)"
Insérer avant quelques enregistrements dans la table prets, avec des requetes INSERT
SELECT d.id_document, titre, auteur, editeur
FROM prets p, documents d
WHERE d.id_document = p.id_document
AND retour=0 ;
" Quels sont les documents empruntés par les élèves de la 6A ? "
SELECT prenom, nom, classe, auteur, titre
FROM inscrits, prets, documents
WHERE classe = '6a'
AND inscrits.id_inscrit = prets.id_inscrit
AND documents.id_document = prets.id_document ;
- Sous-requêtes
Il faut attendre la version 4.1 de Mysql pour accepter les sous-requetes générales.
A l'aide de Phpmyadmin (onglet opérations), faites une copie (structure seule) de la structure de la table documents dans la table doc. On peut alors copier des enregistrements de documents satisfaisant à une requete (le titre commence par "les"), dans la nouvelle table doc
INSERT INTO doc SELECT * FROM documents WHERE titre LIKE 'les%' ;
- Requetes avec expressions régulières
Le langage des expressions régulières est compris par Mysql. On place le motif dans une clause WHERE après le mot-clé REGEX.
Exemples à tester et à commenter :
SELECT * FROM documents WHERE titre REGEXP '^l.*[rt]$' ;
SELECT * FROM documents WHERE titre REGEXP '^a.{5}r' ;
SELECT * FROM documents WHERE titre REGEXP ' et ' ;
SELECT * FROM documents WHERE titre REGEXP 'vie| bon' ;
SELECT * FROM documents WHERE titre REGEXP '[[:digit:]]+' ;
SELECT * FROM documents WHERE titre REGEXP '[a-z]{5}' ;
- Exercices
- Récupérer tous les documents prêtés (autrement dit les rendre de nouveau disponibles)
- Noter un nouveau pret, du document 11 à l'inscrit 15, avec une date de retour prévue dans 2 semaines
- Trouver les auteurs dont le nombre d'ouvrages au CDI est supérieur à 5
- Liste des élèves de la 6A ayant empruntés un document non retourné (retour = 0)