Site A.T.L.A.N.T.I.C-83
COURS = Initiation aux bases de données (Chapitre_6) - VERSION: 1.0 (M.A.J: 26/11/2017)
- AUTEUR(s): Bernard GIACOMONI
Ecran large mobile
Retour
sommaire cours

VI.LE LANGAGE SQL ET LES A.P.I PHP-MySQL:

VI.1.APERÇU DU LANGAGE SQL:

VI.1.1.INTRODUCTION:

Notre intention n'est pas de présenter ici un manuel de référence de SQL, que l'on peut par ailleurs trouver facilement en ligne sur le web. Les pages qui suivent visent à donner au lecteur un aperçu du langage SQL présenté en fonction des traitements à accomplir (création de la structure d'une BD, création ou modification du contenu, recherche de données dans une BD, etc.). Les différentes requêtes sont décrites uniquement dans leurs formes fondamentales.

VI.1.2.STRUCTURE GÉNÉRALE DES REQUÊTES SQL:

Les REQUÊTES SQL se présentent sous la forme de chaînes de caractères constituées de la concaténation de mots clefs (que l'on écrit en général en majuscules) et de valeurs de paramètres se rapportant à ces mots clefs. Les mots-clefs représentent des CLAUSES permettant de définir le type de la requête ou de particulariser son exécution. Par exemple, la requête de création de la base de données 'bibliotheque' peut s'écrire :
CREATE DATABASE IF NOT EXISTS `bibliotheque` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci
COMMENTAIRES:
Cette requête nous permet d'avoir un aperçu de la manière dont une requête SQL est construite:
  • Le mot clef CREATE indique qu'il s'agit d'une requête concernant la création d'un élément;
  • Le mot clef DATABASE précise qu'il s'agit de la création d'une base de données (une requête CREATE peut aussi concerner une TABLE);
  • La suite de mots clefs IF NOT EXISTS indique que la création de la BD est conditionnée au fait qu'aucune BD de ce nom n'est connue du SGBD;
  • La valeur de paramètre 'bibliothèque' qui suit indique le nom de la BD à créer;
  • La suite de mots clefs DEFAULT CHARACTER SET indique que ce qui la suit est le nom du jeu de caractères associé par défaut à la BD (c'est à dire aux différents champs textuels) qui seront créés par la suite dans cette table);
  • La valeur de paramètre latin1 spécifie le nom du jeu de caractères choisi (latin1 est une constante prédéfinie);
  • Le mot clef COLLATE indique que ce qui suit est le mode d'interclassement (ordre alphabétique) par défaut. Ici, il s'agit de latin1_swedish_ci, qui est associé au jeu de caractères latin1 (jeu ISO-8859-1).
Ce premier exemple nous permet de mettre en exergue la structure générale du début d'une requête:
  • le premier mot-clef d'une requête indique l'action invoquée par la requête:
    • CREATE pour créer un élément,
    • DROP pour supprimer un élément,
    • ALTER pour supprimer la STRUCTURE d'un élément,
    • INSERT pour ajouter des entrées,
    • Etc.
  • Le mot clef qui suit immédiatement indique la nature de l'élément sur lequel s'applique l'action: DATABASE pour une base de données, TABLE pour une table, etc;
  • La mention IF NOT EXISTS, si elle est présente, permet de conditionner la création d'un élément au fait qu'il n'existe aucun élément de ce type portant le même nom;
  • On trouve ensuite le nom de l'élément sur lequel s'applique l'action (dans l'exemple ci-dessus, la requête CREATE s'applique à une BASE DE DONNEES que l'on veut appeler 'bibliothèque';
  • Les spécifications qui suivent seront étudiées par la suite: elle dépendent du type de l'action invoquée.

VI.1.3.REMARQUE: CONVENTIONS UTILISÉES DANS CE DOCUMENT POUR DÉCRIRE LA STRUCTURE DES REQUÊTES:

Pour décrire la structure générale de chaque requête, nous utiliserons les conventions suivantes:
  1. Le texte inclus entre deux chevrons (< ... >) désigne un élément que l'on décrira plus tard. Exemple : dans une requête CREATE DATABASE, '<identifiant du jeu de caractères par défaut>' peut être remplacé par 'latin1';
  2. Les crochets ([…]) désignent des éléments optionnels. Par exemple, dans une requête CREATE, on peut omettre IF NOT EXIST : on peut donc écrire dans la structure logique de CREATE DATABASE: CREATE DATABASE [IF NOT EXISTS] '<nom de la BD>';
  3. Le caractère / permet d'écrire des listes d'options entre lesquelles il est possible de choisir lors de l'écriture de la requête. Par exemple, dans le schéma logique d'une requête CREATE DATABASE, on pourra trouver: DEFAULT CHARACTER SET ascii/binary/latin1/latin2, la liste ascii, binary, latin1, latin2 indiquant les jeux de caractères qui peuvent être choisis;
  4. Des crochets peuvent englober d'autres crochets. Par exemple, dans une requête CREATE DATABASE, le mot clef COLLATE ne peut être présent que si un jeu de caractère par défaut a été défini. On écrira donc la structure logique de la manière suivante:
    [ DEFAULT CHARACTER SET <jeu de caractère> [ COLLATE <type d'interclassement> ] ],
    Ce qui signifie que l'option COLLATE est une sous-option de DEFAULT CHARACTER SET.
Ceci donne, pour la description logique de CREATE DATABASE:
CREATE DATABASE [IF NOT EXISTS] '<nom de la bd>'
[DEFAULT CHARACTER SET <jeu de caractère> [ COLLATE <type d'interclassement> ]]

VI.1.4.CREATION DE LA STRUCTURE D'UNE BASE DE DONNEES:

CREATION DE LA BASE DE DONNEES ELLE-MÊME:

Nous avons déjà abordé cette requête dans les pages précédentes. La structure logique d'une requête CREATE DATABASE, réduite aux options fondamentales, peut s'écrire ainsi:
CREATE DATABASE [IF NOT EXISTS] `bibliotheque` [DEFAULT CHARACTER SET <nom du jeu de caractères>
[COLLATE <Nom de l'interclassement utilisé>] ]
EXEMPLE:
La requête CREATE DATABASE `bibliotheque` DEFAULT CHARACTER SET ascii COLLATE ascii_general_ci crée un base de données nommée "bibliotheque', qui emploie par défaut le jeu de caractères "ascii" et qui utilise la méthode d'interclassement 'ascii_general_ci'.
REMARQUE: Cette requête crée une base de donnée vide (sans aucune table.

NOTION DE BASE DE DONNÉES ACTIVE - REQUÊTE USE:

Dans un SGBD, plusieurs bases de données peuvent être définies. Or, dans le but d'alléger la syntaxe d'écriture des requêtes, la plupart decelles-ci ne spécifient pas le nom de la base de données à laquelle elles s'appliquent (c'est le cas, en particulier de la requête de création d'une TABLE, que nous allons aborder tout de suite après ce paragraphe). Le problème est résolu par la notion de "base de donnée active": à un instant donné, une seule base de donnée est déclarée ACTIVE. Cette déclaration est effectuée par la requête USE, dont le schéma logique est:
USE '<nom d'une des bases de données définies dans le SGBD>'
EXEMPLE:
la requête USE 'bibliothèque' doit précéder toute requête de création de tables dans la base de données bibliothèque.

CREATION DE TABLES:

La forme générale de la requête de création d'une table est:
CREATE TABLE '<nom de table>'
(
<déclaration du champ n° 1>,
............................
<déclaration du champ n° n>,
[PRIMARY KEY ('<nom de champ>')],
[KEY `<Nom de l'index>` (`<Nom du champ déclaré comme index>`)],
............................
[KEY `<Nom de l'index>` (`<Nom du champ déclaré comme index>`)],
)
[ENGINE= MyISAM/InnoDB/MEMORY/MERGE/CSV/...]
[DEFAULT CHARSET= <jeu de caractères 1>/../<jeu de caractères n> ]
[COMMENT='<commentaire sur la table>']
[AUTO_INCREMENT=<valeur entière auto incrément>];
DÉCLARATION DES CHAMPS: Chacune des déclarations de champs obéit à la syntaxe suivante:
'<nom du champ>' <format de donnée> [UNSIGNED] [NOT NULL] [AUTO_INCREMENT] [COMMENT '<commentaire libre>']
Par exemple, la déclaration: Id_abonne int(2) UNSIGNED NOT NULL AUTO_INCREMENT permettra de définir l'attribut Id_abonne comme étant un entier sur 2 octets (format int(2), non signé, non nul, s'auto incrémentant automatiquement pour chaque nouvelle entrée et utilisé comme clef primaire.
DÉCLARATION DE LA CLEF PRIMAIRE: Pour déclarer un champ en tant que CLEF PRIMAIRE, on utilisera la déclaration:
PRIMARY KEY '<nom du champ>'
Par exemple, la déclaration: PRIMARY KEY 'id_li', incluse dans la déclaration de la table 'livres' indique que le champ id_li de cette table est une CLEF PRIMAIRE de la table.
DÉCLARATION D'UN INDEX: Pour déclarer un champ en tant qu'index, on utilisera la déclaration:
KEY '<nom de l'index> ('<nom du champ>')
Par exemple, la déclaration : KEY 'IndexLivre' (`fk_id_li`), incluse dans la déclaration de la table 'exemplaire' indique que le champ fk_id_li de cette table est un INDEX identifié par le nom 'IndexLivre'.
PARAMÈTRES PAR DÉFAUT DE LA TABLE: La dernière ligne permet de spécifier divers paramètres par défaut attachés à la table. Ceux-ci, s'ils sont spécifiés, prennent le pas sur les paramètres par défaut de la BD:
Spécification du moteur de stockage à utiliser pour la table:
[ENGINE= MyISAM/InnoDB/MEMORY/MERGE/CSV/...]
Spécification du jeu de caractères par défaut:
[DEFAULT CHARSET= <jeu de caractères 1>/../<jeu de caractères n> ]
Commentaire associé à la table:
[COMMENT='<commentaire sur la table>']
Valeur de l'auto-incrément:
[AUTO_INCREMENT=<valeur entière auto incrément>]
EXEMPLE DE DÉCLARATION DE TABLE:
Création de la table abonnes de la base bibliotheque, avec 6 champs appelés id_ab, nom_ab, prenoms_ab, adresse_postale_ab, email_ab et telephone_ab, une clef primaire (champ 'id_ab') et un index placé sur le champ 'nom_ab':
USE 'bibliotheque'; –- uniquement si la BD active n'est pas définie --

CREATE TABLE IF NOT EXISTS `abonnes`
(
`id_ab` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id. des abonnés',
`nom_ab` varchar(100) NOT NULL COMMENT 'nom de l'abonné',
`prenoms_ab` varchar(100) NOT NULL COMMENT 'prénoms de l'abonné',
`adresse_postale_ab` varchar(255) NOT NULL COMMENT 'adresse postale de l'abonné',
`e_mail_ab` varchar(30) NOT NULL COMMENT 'adresse e_mail de l'abonné',
`telephone_ab` int(30) NOT NULL COMMENT 'numéro de téléphone de l'abonné',
PRIMARY KEY (`id_ab`)
KEY `NomAbonnes` (`nom_ab`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des abonnée' AUTO_INCREMENT=1 ;

SUPPRESSION DE BASES DE DONNÉES ET DE TABLES:

Ces suppressions peuvent être effectuées grâce aux requêtes DROP:
DROP TABLE '<nom de table>';<br /> DROP DATABASE '<nom de bd>';
En ce qui concerne la requête DROP TABLE, il faut (bien sûr) que la BD active soit définie (requête USE).

REMARQUE: DÉFINITION D'UNE CLEF ÉTRANGÈRE:

Les requêtes CREATE DATABASE et CREATE TABLE permettent à elles-seules de créer la STRUCTURE d'une base de données (et non son contenu), à une exception près, la définition des CLEFS ÉTRANGÈRES. En effet, la définition de clefs étrangères suppose que l'ensemble des tables de la BD soit entièrement défini. Nous verrons par la suite que les CLEFS ÉTRANGÈRES doivent être définies par des requêtes ALTER TABLE que nous allons aborder maintenant.

VI.1.5.MODIFICATION DE LA STRUCTURE D'UNE BASE DE DONNEES:

GÉNÉRALITÉS:

Les requêtes ALTER TABLE permettent de modifier la structure d'une base de données existante. Les modifications possibles sont:
  • Ajouter un attribut (un champ);
  • Changer les propriétés d'un attribut;
  • Supprimer un attribut;
  • Ajouter une CONTRAINTE sur un attribut (c'est à dire, définir un attribut comme CLEF ETRANGÈRE).
AJOUTER UN ATTRIBUT:
Le schéma de la requête est:
ALTER TABLE '<nom table>' ADD '<nom de l'attribut à ajouter>' <propriétés de l'attribut>
EXEMPLE: Ajout de l'attribut 'date_f' à la table 'factures', la date_f étant le timestamp au format POSIX (date en secondes depuis le 01/01/1970);
ALTER TABLE 'factures' ADD 'date_f' TIMESTAMP UNSIGNED NOT NULL] COMMENT 'Date de facturation';
MODIFIER UN ATTRIBUT:
Le schéma de la requête est:
ALTER TABLE '<nom table>' CHANGE '<nom de l'attribut à modifier>' <propriétés de l'attribut>
EXEMPLE: Dans la table 'livres' l'attribut 'presentation_li' a dans un premier temps été défini comme une chaîne de caractères de 255 octets (type varchar(255)). On veut pouvoir saisir des textes beaucoup plus longs. Pour cela, on modifie le nom de l'attribut en 'presentation_li_t et le type de l'attribut en 'TEXT' (jusqu'à 64ko):
ALTER TABLE 'livres' CHANGE 'presentation_li' 'presentation_li_t' 'TEXT' ;
SUPPRIMER UN ATTRIBUT:
Le schéma de la requête est:
ALTER TABLE '<nom table>' DROP '<nom d'attribut>' ;
EXEMPLE: suppression de l'attribut presentation_li de la table livres:
ALTER TABLE 'livres' DROP 'presentation_li' ;
DÉFINIR UNE CLEF ÉTRANGÈRE:
Le schéma de la requête est:
ALTER TABLE '<nom table>' ADD CONSTRAINT '<nom de contrainte>' FOREIGN KEY ('<nom de clef étrangère>')
REFERENCES '<nom de la table de référence>' ('<nom de l'attribut de référence>'`) 
EXEMPLE: Ajout dans la table 'exemplaires' de la clef étrangère `fk_id_li`, faisant référence à à l'attribut id_li de la table livres. Cette contrainte entre les tables exemplaires et la table livres s'appelle LivreExemplaire;
ALTER TABLE 'exemplaires' ADD CONSTRAINT `LivreExemplaire' FOREIGN KEY (`fk_id_li`) REFERENCES `livres' (`id_il`) 

VI.1.6.MODIFICATION DU CONTENU D'UNE BASE DE DONNEES:

GÉNÉRALITÉS:

Les requêtes qui permettent la modification du CONTENU d'une base de données sont:
  • INSERT INTO, qui permet d'ajouter une entrée (une ligne) à une table;
  • UPDATE, qui permet de modifier les champs d'une ou plusieurs entrées (lignes);
  • DELETE FROM, qui permet de supprimer une ou plusieurs entrées (lignes) d'une table.

REQUÊTE INSERT INTO:

Le schéma logique de cette requête est :
INSERT INTO '<nom de BD'>.'<nom de table>' ( '<nom du champ 1>', …, '<nom du champ N>' ) VALUES ( '<valeur du champ 1>',...,'<valeur du champ N>' )
EXEMPLE: Insère dans la table 'abonnes' de la base 'mabase' l'entrée dont les attributs login et password ont respectivement les valeurs 'superman' et ''xxSuPer %'':
INSERT INTO `mabase`.`abonnes` ( 'login', 'password' ) VALUES ( 'superman','xxSuPer %' );

REQUÊTE UPDATE:

Le schéma logique de cette requête est :
UPDATE '<nom de table>' SET '<nom champ 1>'='<valeur champ 1>',.., '<nom champ n>'='<valeur champ n>' [WHERE <Condition>];
Si la clause WHERE est omise , toutes les entrées de la table sont modifiées (mises à jour) en fonction des indications données par la clause SET. Si la clause WHERE est libellée, seules les entrées satisfaisant à la condition sont modifiées.
EXEMPLE: Modification du champ 'e_mail' de chacune des entrées de la table 'abonnes' dont le champ 'login' contient la valeur 'spiderman' et dont le mot de passe est 'forever':
UPDATE 'abonnes' SET 'e-mail'='spiderman.araignee.fr' WHERE 'login'='spiderman' AND 'password'='forever';

REQUÊTE DELETE FROM:

Le schéma logique de cette requête est :
DELETE FROM '<nom de table>' WHERE <Condition>
EXEMPLE: Suppression de toutes les entrées de la table 'abonnes' dont les champs 'login' contiennent la valeur 'spiderman'.
DELETE FROM 'abonnes' WHERE 'login'='spiderman';

VI.1.7.LA SÉLECTION ET L'EXTRACTION DES DONNÉES:

PRINCIPE:

La sélection et l'extraction des données de la base de données s'effectuent grâce à la requête SELECT. Les fonctionnalités principales de cette requête sont:
- D'une part de permettre la SÉLECTION d'entrées d'une ou plusieurs tables d'un base de données en fonction de conditions imposées aux valeurs des attributs de ces entrées,
- D'autre part, d'extraire les valeurs des attributs des entrées sélectionnées pour les mettre à disposition des applications utilisatrices.
Par exemple, sélectionner toutes les entrées d'une table T dont l'attribut A vaut 10 et extraire les valeurs sélectionnées.
La requête SELECT est probablement la requête la plus utilisée lors de l'utilisation d'une base de données par une application, d'autant plus que cette requête permet de lancer d'autres requêtes en fonction de la sélection effectuée: elle agit un peu comme une instruction itérative conditionnelle des langages de programmation classiques.

SCHEMA LOGIQUE DE LA REQUÊTE SELECT:

Le schéma logique simplifié de cette requête est :
SELECT <Liste de noms d'attributs à sélectionner, séparés par des virgules>
FROM <nom de table>
[ WHERE <condition sur la valeur des champs de la table> ]
[ ORDER BY <nom du champ sur lequel est effectué l'ordonnancement> ] [ ASC/DESC ]
[ LIMIT <première entrée à prendre en considération>, <nombre d'entrées à traiter> ];
COMMENTAIRES:
  • La clause WERE <CONDITION> permet de ne sélectionner dans la table indiquée par la clause FROM que les entrées répondant à la condition mentionnée: c'est la fonction de sélection des entrées;
  • La liste des noms d'attributs à sélectionner permet de ne sélectionner dans les entrées sélectionnées que les attributs figurant dans cette liste: c'est la fonction de sélection des attributs. Si la liste des attributs est remplacée par une "*", tous les attributs de la table sont sélectionnés;
  • La clause ORDER BY permet de présenter les entrées sélectionnées par valeurs croissantes ou décroissantes de la valeur du champ figurant dans cette clause. Si la valeur de ce champ n'est pas numérique, l'ordonnancement se fera par ordre alphabétique;
  • La clause LIMIT permet de limiter la recherche des entrées à sélectionner: le premier paramètre concerne la première entrée à traiter (nombre entier), le deuxième paramètre concerne le nombre d'entrées consécutives à traiter (nombre entier).
EXEMPLE: Sélection des valeurs des attributs 'nom' et 'prénom' des entrée de la table 'eleves' dont l'attribut 'classe' est CM2 (on sélectionne et on extrait les noms et prénoms des élèves de la classe de CM2):
SELECT nom, prenom FROM eleves WHERE classe = 'CM2';

RÉCUPÉRATION DES VALEURS DES CHAMPS SÉLECTIONNÉS:

Les résultats retournés par la requête SELECT sont rangés dans un TABLEAU ASSOCIATIF dont les lignes correspondent aux entrées satisfaisant la condition WHERE et dont les COLONNES correspondent aux ATTRIBUTS sélectionnés. Supposons la requête :
SELECT nom, prenom, classe FROM eleves WHERE prenom = 'Claude';
Si dans trois entrées de la table eleves, le nom de l'élève est Claude, la requète retournera un tableau semblable à celui-ci:
nomprénomclasse
DupondClaudeCM1
DuvalClaudeCM2
LegrandClaudeCP
La récupération de ces données par les applications utilisatrice se fait par l'intermédiaire des A.P.I. dédiés: en général, les noms des fonctions correspondantes sont en général formés à partir du "suffixe" fetch_array que l'on peut traduire en français par "récupérer le tableau" (On aura ainsi dans l'API PHP de MySQL la fonction mysql_fetch_array).

VI.1.8.LES JOINTURES:

JOINTURE DE DEUX TABLES:

Dans le langage SQL, les opérations de jointure de tables sont réalisées en utilisant des requêtes SELECT comprenant une clause particulière, la clause JOIN. La structuration des requêtes SELECT ne permettant de ne définir qu'une seule table cible (par la clause FROM), la clause JOIN à l'intérieur d'une requête SELECT va permettre de définit une nouvelle table qui va être jointe à la première:
Le schéma logique d'une requête de jointure est le suivant:
SELECT <liste d'attributs des deux tables> FROM <nom table 1>
<LEFT/RIGHT/INNER/OUTER/FULL> JOIN <nom table 2>
ON <nom attribut table 1> = <nom attribut table table2>
[ WHERE <Condition de sélection des entrées> ]
[ ORDER BY <définition de l'ordre de présentation des entrées> ]
COMMENTAIRES:
  • La clause FROM permet de définit une première table à joindre;
  • Les lignes affichées en rouge sont celles qui permettent de réaliser la jonction avec une deuxième table;
  • La liste de mots clefs <LEFT/RIGHT/INNER/OUTER/FULL> avant la clause JOIN permet de spécifier le type de jointure que l'on veut réaliser: jointure à gauche, jointure à droite, jointure interne, etc.
  • Le nom de table après la clause JOIN permet de déterminer la deuxième table de l'opération de jointure;
  • La clause ON permet de spécifier les attributs des deux tables suivant lesquels la jointure est réalisée.
  • Remarquons que ces deux attributs peuvent être notés suivant la notation <nom de table>.<nom d'attribut>.
EXEMPLE:
Création à partir de la table des livres et de la table des exemplaires disponibles, une table listant l'ensemble des exemplaires disponibles avec les livres auxquels ils correspondent:
SELECT reference_ex, livres.titre_li FROM exemplaires LEFT JOIN livres ON livres.id_li = exemplaires.fk_id_li
En fait, cette opération permet de réaliser l'association Correspondre du MCD de la bibiliothèque étudiée précedemment.
REMARQUES:
  • Les clauses WHERE et ORDER BY ayant été omises, la jointure sera effectuée sur toutes les entrées des deux tables.
  • D'autre part, du fait de la liste d'attribut de la clause SELECT,la table de jointure ne comprendra que deux colonnes: reference_ex et livres.titre_li. Remarquons que le deuxième attribut, qui appartient à la table qui n'est pas désignée par la clause FROM, doit être indiqué avec son nom de table;
  • La table de jointure obtenue est TEMPORAIRE (elle ne survit pas à l'exécution de la requête). Le résultat de l'opération sera le tableau associatif retourné par la requête SELECT. Celui-ci sera de type exemplaires_livres ( reference_ex, titre_li ). Il permettra d'associer à chaque exemplaire le livre qui lui correspond;

JOINTURE DE PLUS DE DEUX TABLES:

Il est possible d'effectuer une jointure de plusieurs table. Cette opération consiste à joindre TRANSITIVEMENT une table A à une table B, puis le résultat à une table C, et ainsi de suite. Le schéma logique d'une telle jointure est le suivant:
SELECT <liste d'attributs des tables>
FROM <nom table 1>
<LEFT/RIGHT/INNER/OUTER/FULL> JOIN <nom table 2>
ON <condition d'égalité des attributs de jonction>
<LEFT/RIGHT/INNER/OUTER/FULL> JOIN <table 3>
ON <condition d'égalité des attributs de jonction>
.....................................................
<LEFT/RIGHT/INNER/OUTER/FULL> JOIN <table n>
ON <condition d'égalité des attributs de jonction>
WHERE <condition de sélection des entrées>
ORDER BY <définition de l'ordre de présentation des entrées>

EXEMPLE: Jointure de 3 tables (auteurs, auteurs_livres, livres) :
SELECT id_au, livres.id_li FROM auteurs
INNER JOIN auteurs_livres ON auteurs.id_au = auteurs_livres.fk_id_au
INNER JOIN livres ON livres.id_li = auteurs_livres.fk_id_li
Cette triple jointure permet d'obtenir une table que l'on pourrait noter auteurs_et_livres ( id_au, id_li) qui permet d'associer chaque livre à son auteur. Elle réalise donc l'association Ecrire du MCD de la bibiliothèque étudiée précedemment.

VI.2.Les A.P.I PHP-MySQL:

VI.2.1.REMARQUE PRÉLIMINAIRE:

Nous allons étudier les API permettant d'interfacer un SGBD MySQL à partir d'un programme PHP. Il s'agit là d'un cas relativement bien répandu car MySQL fait partie de la suite APACHE qui équipe les serveurs LAMP (linux) et WAMP (microsoft window).
Actuellement (fin 2017), trois API PHP/MySQL sont disponibles:
  • L'API MYSQL, qui est considéré comme obsolète à partir de la version 5.0 de PHP et ne sera plus disponible à partir de la version 7.0;
  • L'API MYSQLi (MySQL improved, c'est à dire: MySQL amélioré);
  • L'API PDO (PHP Data Object).
L'API MySQL "de base" étant obsolète, il n'est plus conseillé de l'utiliser pour de nouvelles applications. Cependant, on le retrouve dans un grand nombre (peut être une majorité ?) d'applications existantes. De ce fait, il n'est pas encore inutile de se familiariser avec lui, ne serais-ce que dans le cadre d'actions de maintenance et évolution d'applications existantes.
L'API MySQLi est une version "OBJET" de l'API MySQL de base: chaque connexion à un SGB est encapsulée dans un OBJET instancié à partir d'une classe mysqli. Les méthodes de cet objet permettent d'émettre vers le SGBD des requêtes SQL ou d'accéder aux informations de compte-rendu. La particularité de cet API est qu'il met également à disposition des utilisateurs des FONCTIONS pratiquement identiques à celles de l'API MySQL: en général, une fonction dont le nom dans l'API MySQL est mysql_*** s'écrira mysqli_*** dans l'API MySQLi. Un logiciel écrit en MySQL est donc très facilement transformable en MySQLi.
L'API PDO est également un API "OBJET": là aussi, chaque connexion à un SGB est encapsulée dans un OBJET instancié à partir de la classe PDO. Les méthodes de cet objet permettent également d'émettre vers le SGBD des requêtes SQL ou d'accéder aux informations de compte-rendu. Cependant, cet API est incompatible avec un programme écrit en MySQL de base.
Dans le cadre de ce cours, l'API PDO ne sera pas étudié. Comme la transformation des appels MySQL "de base" en appels MySQLi "procéduraux" est très facile, nous avons choisi de présenter les fonctions de l'A.P.I MySQL de base et de donner en même temps leur version "OBJET" telle qu'elle est prévue par l'API MySQLi.

VI.2.2.PRÉSENTATION DE L'API MySQL:

L'API MySQL permet à un programme écrit en PHP de communiquer avec un SGBD MySQL par l'intermédiaire d'un serveur (notamment un serveur APACHE) . Il permet d'expédier vers ce SGBD des REQUÊTES SQL et de récupérer les réponses de celui-ci. MySQL permet donc de manipuler des BASES DE DONNÉES et des TABLES:
  • Créer, configurer, modifier, détruire des BASES DE DONNÉES;
  • Créer, supprimer, modifier des TABLES;
  • Accéder au contenu des tables pour en extraire des informations ou pour mettre à jour les valeurs des attributs ;
  • Créer de nouvelles tables à partir des tables existantes par divers procédés (jonction, projection, etc.).
REMARQUE: Le SGBD MySQL est en général accompagné d'un IHM de gestion manuelle des bases de données appelé PHPMyAdmin.

VI.2.3.FORME GÉNÉRAL DES APPELS A L'API MySQL en PHP:

MySQL offre aux applications utilisatrices une bibliothèque de fonctions PHP qui permettent d'activer des requêtes SQL sur une base de données. La syntaxe générale de ces fonctions est:
<compte-rendu booleen> = mysql_<Nom fonction> ( <paramètres> );
EN PARTICULIER:
Les fonctions dont le schéma est: <Nom de variable PHP> = mysql_query ( '<requête SQL>' );
permettent d'activer là requète SQL passée en paramêtre et de récupérer son résultat dans la variable PHP.
EXEMPLE:
l'appel de fonction suivant dans un programme PHP:
$R = mysql_query ( 'CREATE DATABASE `bibliotheque` DEFAULT CHARACTER SET ascii COLLATE ascii_general_ci' );
Crée une base de données de nom 'bibliothèque' avec le jeu de caractère ascii par défaut et l'interclassement ascii_general_ci. Le résultat de la requête (compte-rendu de création) est récupéré dans la variable $R.
Nous pouvons voir qu'il est très facile de programmer un programme SQL par l'intermédiaire de l'API MySQL de base: une seule fonction suffit, la fonction mysql_query. Cependant, l'API contient également d'autres fonction qui servent à récupérer les résultats, à gérer la connexion réseau avec la base de données, à détecter les erreurs, etc. Nous allons aborder ces fonctions dans ce qui suit.
REMARQUE-VERSION MySQLi OBJET:
$R = $Connexion->query ( 'CREATE DATABASE `bibliotheque` DEFAULT CHARACTER SET ascii COLLATE ascii_general_ci' ):
Crée une base de données de nom 'bibliothèque' avec le jeu de caractère ascii par défaut et l'interclassement ascii_general_ci. Le résultat de la requête (compte-rendu de création) est récupéré dans la variable $R. La variable $Connexion est un OBJET encapsulant une connexion particulière du logiciel au SGBD et la méthode $Connexion->Query() permet d'adresser une requête SQL au SGBD.

VI.2.4.ACCES AU SGBD:

PROCEDURE D'ACCÉS AU SGBD

Les SGBD MySQL sont hébergés dans des SERVEURS INFORMATIQUES en réseau (généralement, des serveurs APACHE). De ce fait on y accède avec une procédure de connexion CONNEXION "client-serveur" avec identification du client (l'utilisateur) par saisie d'un identificateur client et d'un mot de passe.

CONNEXION D'UN CLIENT AU SGBD

La fonction de l'API MySQL qui permet à un utilisateur de se connecter au SGBD est mysql_connect. Sa syntaxe générale est la suivante:
<compte-rendu booléen> = mysql_connect ("<URL du serveur>","<Id. de connexion>","<mot de passe>");
  • La fonction retourne un compte-rendu booléen: sa valeur est TRUE si la connexion a réussi, FALSE dans le cas contraire;
  • Si l'application utilisatrice n'est pas dans la même machine que le serveur.L'URL du serveur est de la forme:
    http://www.<Nom de domaine du serveur>:<Numéro de port>
  • Si l'application est dans la même machine que le serveur, l'URL est de la forme:
    http://localhost:<Numéro de port>
EXEMPLE:
$CR = mysql_connect("http://www.monserveur.com:3306","MonIdUtilisateur","MonMotDePasse");
Cette requête permet à un utilisateur de se connecter à un SGBD situé à l'adresse WEB http://www.monserveur:3306, avec l'identifiant "MonIdUtilisateur" et le mot de passe "MonMotDePasse".
REMARQUE-VERSION MYSQLi OBJET:
$Connexion = new mysqli( "http://www.monserveur.com:3306","MonIdUtilisateur","MonMotDePasse", "MaBase" );
Cette requête crée un objet $Connexion à partir de la classe mysqli. Cet objet représente la connexion à un SGBD situé à l'adresse WEB http://www.monserveur:3306, avec l'identifiant "MonIdUtilisateur" et le mot de passe "MonMotDePasse". A la différence du MySQL de base, un nom de base de donnée "par défaut" peut être choisi (le paramètre "MaBase" peut aussi être omis).

DÉCONNEXION D'UN CLIENT APRÈS UTILISATION DU SGBD:

La fonction de déconnexion de la connexion en cours est simplement:
mysql_close();
REMARQUE:En MySQLI OBJET on écrit: $Connexion->close(), $Connexion étant l'objet représentant la connexion.

SÉLECTION D'UNE DES BASES DE DONNÉES GÉRÉES PAR LE SGBD:

La fonction mysql_select_db permet de sélectionner, à l'intérieur du SGBD auquel on est connecté, la base de donnée avec laquelle on veut travailler. En effet, cette fonction permet d'émettre vers le SGBD la requête USE '<Nom de base de donnée>'. Sa syntaxe générale est la suivante:
<compte-rendu booléen> = mysql_select_db ("<nom de base de données à sélectionner>");

REMARQUE:

La structure générale d'une séquence de communication d'une application avec une base de données peut donc s'écrire:
$R1 = mysql_connect("http://www.monserveur.com:3306","MonIdUtilisateur","MonMotDePasse");
if ( $R1 !== false )
{
$R2 = mysql_select_db ("<nom de base de données à sélectionner>");
if ( $R2 !== false )
{
<Séquence d'utilisation de la BD: lecture, écriture, etc.>
} $R3 = mysql_close ();
}

VERSION MySQLi OBJET:

La même structure générale peut s'écrire en MySQLi OBJET:
$Connexion = new mysqli ("http://www.monserveur.com:3306","MonIdUtilisateur","MonMotDePasse" );
if ( $Connexion !== false )
{
$R $Connexion->select_db ("<nom de base de données à sélectionner>");
if ( $R !== false )
{
<Séquence d'utilisation de la BD: lecture, écriture, etc.>
} $R = $connexion->close ();
}

VI.2.5.RÉCUPÉRATION DU RÉSULTAT D'UNE REQUÊTE SELECT:

Nous avons vu précédemment qu'une requête SQL SELECT renvoie un tableau associatif contenant les champs correspondant aux colonnes sélectionnées et les entrées qui satisfont à la condition WHERE du sélect si celle-ci existe (toutes les entrées si la condition where est omise). Cependant, la structure de données retournée n'est pas compatible avec le format des tableaux PHP. Il est donc nécessaire que l'API MySQL comprenne une fonction capable de récupérer cette donnée sous une forme compatible avec ce langage. Cette fonction est:
<Ligne du tableau obtenu par SELECT> = mysql_fetch_array ( <Compte-rendu renvoyé par la requête SELECT> );
Cette fonction lit LIGNE PAR LIGNE la structure renvoyée par SELECT et place le résultat de la lecture de CHAQUE LIGNE dans un tableau associatif dont les index correspondent aux noms des colonnes renvoyées et dont les valeurs correspondantes aux index sont les valeurs des champs correspondants de l'entrée lue.
EXEMPLE:
Supposons que l'appel de fonction:
$R = mysql_query ('SELECT nom, prenom FROM Eleves WHERE classe = "CM2" ' );
retourne dans $Ligne la structure suivante:
nomprénom
DupondEric
DuvalClaude
LegrandKevin
La variable PHP $R, dans laquelle est placé le résultat de la requête SELECT n'est pas directement assimilable a un tableau PHP: il sera par exemple impossible de récupérer le prénom de la deuxième entrée en faisant $R(2, 'prénom' ). En revanche, la fonction mysql_fetch-array permettra de récupérer ligne par ligne les résultats dans un tableau PHP.
Le code ci-dessous affichera sur 3 lignes les noms et prénoms de chaque entrée du tableau résultat:
$R = mysql_query ( "SELECT nom, prenom FROM Eleves WHERE classe = 'CM2'" );
$i = 1;
while ( ( $Ligne = mysql_fetch_array($R)!= FALSE ) // Chaque appel de mysql_fetch_array récupèrera les champs une des entrées du tableau
{
echo 'Entrée n° '.$i.': nom = '.$Ligne["nom"].' prénom = '.$Ligne["prénom"].'<br />';
$i++;
}
Le résultat affiché sera:
Entrée n°1: nom = Dupond prénom = Eric
Entrée n°2: nom = Duval prénom = Claude
Entrée n°3: nom = Legrand prénom = Kevin
VERSION MySQLi OBJET:
$Connexion = new mysqli ( <Paramètres de connexion> );
$R = $Connexion->query ('SELECT nom, prenom FROM Eleves WHERE classe = "CM2" ' );>
$i = 1;
while ( ( $Ligne = $Connexion->fetch_array($R)!= FALSE ) // Chaque appel de fetch_array récupèrera les champs une des entrées du tableau
{
echo 'Entrée n° '.$i.': nom = '.$Ligne["nom"].' prénom = '.$Ligne["prénom"].'<br />';
$i++;
}

VI.3.EXEMPLES D'APPLICATIONS:

VI.3.1.REMARQUES PRÉLIMINAIRES:

Les exemples qui suivent, sont écrits en langage PHP. Les noms de variables, de bases de données, de tables et d'attributs sont écrits sans accentuation pour éviter les problèmes inhérents aux jeux de caractères employés. Dans les quatre derniers exemples, on supposera que la bases de données est déja créées. La valeur "localhost:3306" de l'URL correspond à celle d'un serveur local. Elle doit être adaptée en fonction de la machine utilisée pour le test. Les lecteurs qui voudraient expérimenter ces exemples sur des systèmes physiques peuvent le faire en installant sur leur machine un serveur apache (WAMP pour les systèmes WINDOW ou LAMP pour les systèmes LINUX) et en insérant ces exemples dans une page WEB.

VI.3.2.EXEMPLE N° 1 - Création d'une base de données 'ecole':

Nous allons créer une base de données nommée "ecole", la munir d'une table eleves ( nom, prenoms, classe ), puis nous allons enregistrer dans cette table les élèves suivants:
Idnomprénomclasse
1DurandJacquesCM1
3DupondClaudeCE2
7DuvalClaudeCM2
12LegrandClaudeCP
33LagardeFrançoisCM2
Le code PHP correspondant pourrait s'écrire:
// Connexion au SGBD ( URL, Nom, Mot de passe )
mysql_connect( "localhost:3306","MonIdClient","MonMotDePasse");

mysql_query ( 'CREATE DATABASE [IF NOT EXISTS] 'ecole' DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci' );

// Sélection de la base de données 'ecole'
mysql_select_db( 'ecole' );

// Constitution de la requête de création de la table eleves
$Requete = "CREATE TABLE 'eleve'
(
'Id' int(8) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Identificateur numérique de l'élève'] 'nom' varchar(20) COMMENT 'Nom de l'élève',
'nom' varchar(20) COMMENT 'Prénoms de l'élève',
'nom' varchar(20) COMMENT 'Classe de l'élève',
PRIMARY KEY ('Id')]
)[ENGINE= InnoDB DEFAULT CHARSET= latin1 COMMENT='Table des élèves de l'école AUTO_INCREMENT=1"

// Envoi de la requête de création de la table au SGBD
mysql_query ( $Requete );

// Clôture de la connexion au SGBD
mysql_close();

VI.3.3.EXEMPLE N° 2 - Sélection de champs et récupération des valeurs:

Soit, dans la base de données 'ecole', la table eleves ( nom, prenoms, classe ). On veut récupérer les noms et prénoms de tous les élèves de CM2 dans le tableau associatif $T[<numero ligne>]['<nom>']['<prenoms>']:
// Connexion au SGBD ( URL, Nom, Mot de passe )
mysql_connect( "localhost:3306","MonIdClient","MonMotDePasse");

// Sélection de la base de données
mysql_select_db( 'ecole' );

// Sélection des valeurs des attributs Nom et Prénoms des Eleves de CM2
$R = mysql_query( "SELECT nom, prenoms FROM 'eleves' WHERE classe ='CM2'" );

// Récupération du tableau associatif des valeurs
$N = 0;
while ( ( $Ligne = mysql_fetch_array($R) ) != false )
{
$T[$N] = $Lignes;
$N ++;
}

// Clôture de la connexion au SGBD
mysql_close();
En fin de traitement, la table PHP T aura pour contenu:
nomprenomclasse
DuvalClaudeCM2
LagardeFrançoisCM2

VI.3.4.EXEMPLE N° 3 - Ajout d'une entrée dans la table eleves:

Soit de nouveau la table eleves ( nom,prenoms, classe ) de la base de données ecole. On veut ajouter l'élève Jean-Pierre MARTIN dans la classe de CM1:
// Connexion au SGBD ( URL, Nom, Mot de passe )
mysql_connect( "localhost:3306","MonIdClient","MonMotDePasse");

// Sélection de la base de données
mysql_select_db( 'ecole' );

// Ajout de l'élève
$R = mysql_query( "INSERT INTO ecole.eleves ( nom, prenoms, classe ) VALUES ( 'MARTIN', 'Jean-Pierre', 'CM1' )" );

// Cloture de la connexion au SGBD
mysql_close();
En fin de traitement, la table eleves aura pour contenu:
nomprénomclasse
DurandJacquesCM1
DupondClaudeCE2
DuvalClaudeCM2
LegrandClaudeCP
LagardeFrançoisCM2
MartinJean-pierreCM1

VI.3.5.EXEMPLE N° 4 - Modification d'un champ d'une entrée:

L'élève Jacques DURAND vient de passer de CM1 en CM2. On veut donc mettre à jour la table eleves:
// Connexion au SGBD ( URL, Nom, Mot de passe )
mysql_connect( "localhost:3306","MonIdClient","MonMotDePasse");

// Sélection de la base de données
mysql_select_db( 'ecole' );

// Changement de la valeur de l'attribut "classe" pour l'élève Jacques DURAND
$R = mysql_query( "UPDATE eleves SET classe='CM2' WHERE nom='DURAND' AND prenoms='Jacques'" );

// Cloture de la connexion au SGBD
mysql_close();
En fin de traitement, la table eleves aura pour contenu:
nomprénomclasse
DurandJacquesCM2
DupondClaudeCE2
DuvalClaudeCM2
LegrandClaudeCP
LagardeFrançoisCM2
MartinJean-pierreCM1

VI.3.6.EXEMPLE N° 5 - Création de la base de données bibliothèque:

Création de la base de données bibliothèque telle qu'elle a été définie par le MLD du chapitre IV, paragraphe IV.7.4: ci-dessous, le code SQL commenté:
--
-- Création de la base de données 'bibliothèque'(si elle n'existe pas), avec comme option l'utilisation
-- par défaut du jeu de caractères latin 1 (ISO-8859-1) et du type d'interclassement alphabétique 
–- latin1_swedish_ci (ordre alphabétique utilisé en France).
–-
CREATE DATABASE IF NOT EXISTS `bibliotheque` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

--
–- Spécifie que les requêtes qui suivent s'adressent à la base de données bibliothèque
--
USE `bibliotheque`;

–-
–- Première ligne: création de la table 'abonnes'
–- Lignes suivantes: définition de ses champs 'id_ab, 'nom_ab', 'prenoms_ab', 'adresse_postale-ab',
–- 'e_mail_ab' et 'telephone_ab' (champs. Pour chacun des champs, son type de donnée est défini (int(8),
–- varchar(100), etc.
–- id_ab est défini comme une clef primaire (mot clef PRIMARY KEY) autoincrémentée (mot clef 
-– AUTOINCREMENT)
–- La dernière ligne définit : le moteur de BD à utiliser (ici : innoBD), le jeu de caractère par défaut
–- (latin 1) et la valeur d'auto-incrémentation à appliquer pour la table (1).
–-
CREATE TABLE IF NOT EXISTS `abonnes` (
  `id_ab` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id. des abonnés',
  `nom_ab` varchar(100) NOT NULL COMMENT 'nom de l''abonné',
  `prenoms_ab` varchar(100) NOT NULL COMMENT 'prénoms de l''abonné, séparés par des virgules',
  `adresse_postale_ab` varchar(255) NOT NULL COMMENT 'adresse postale de l''abonné',
  `e_mail_ab` varchar(30) NOT NULL COMMENT 'adresse e_mail de l''abonné',
  `telephone_ab` int(30) NOT NULL COMMENT 'numéro de téléphone de l''abonné',
  PRIMARY KEY (`id_ab`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des abonnée' AUTO_INCREMENT=1 ;

–-
–- Les 3 requêtes suivantes définissent la structure des tables 'auteurs', 'auteurs_livres' et 
–- 'emprunts'. Les mots clefs KEY utilisés pour les deux dernières permettent d'associer à certains 
-– champs des INDEX : dans ce cas, cela est nécessaire pour que ces champs puissent être définis plus
–- tard comme des CLEFS ETRANGERES
--
CREATE TABLE IF NOT EXISTS `auteurs` (
  `id_au` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Clef auteurs',
  `nom_au` varchar(100) NOT NULL COMMENT 'Nom de l''auteur',
  `prenoms_au` varchar(100) NOT NULL COMMENT 'prénoms de l''auteur, séparés par des virgules',
  `biographie_au` text NOT NULL COMMENT 'biographie de l''auteur',
  PRIMARY KEY (`id_au`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des auteurs' AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `auteurs_livres` (
  `fk_id_au` int(8) unsigned NOT NULL,
  `fk_id_li` int(8) unsigned NOT NULL,
  KEY `fk_id_au` (`fk_id_au`),
  KEY `fk_id_li` (`fk_id_li`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table de jonction auteurs-livres (association "ecrire"';

CREATE TABLE IF NOT EXISTS `emprunts` (
  `date_em` varchar(30) NOT NULL COMMENT 'Date d''emprunt',
  `duree-em` int(2) NOT NULL COMMENT 'durée en semaines de l''emprunt',
  `fk_id_ab` int(8) unsigned NOT NULL COMMENT 'Clef étrangère (id. de l''abonné emprunteur)',
  `fk_reference_ex` varchar(30) NOT NULL COMMENT 'clef étrangère (référence de l''exemplaire emprunté)',
  KEY `fk_id_ab` (`fk_id_ab`),
  KEY `fk_reference_ex` (`fk_reference_ex`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des emprunts en cours ';

–-
–- Les 2 requêtes suivantes définissent la structure des tables 'exemplaires', et 'livres' et 
–- 'emprunts'. Les mots clefs KEY utilisés pour les deux dernières permettent d'associer à certains 
-– champs des INDEX : dans ce cas, cela est nécessaire pour que ces champs puissent être définis plus
–- tard comme des CLEFS ETRANGERES
--

CREATE TABLE IF NOT EXISTS `exemplaires` (
  `reference_ex` varchar(30) NOT NULL COMMENT 'référence de l''exemplaire: // ',
  `editeur_ex` varchar(255) NOT NULL COMMENT 'éditeur de l''exemplaire',
  `date_achat_ex` varchar(30) NOT NULL COMMENT 'date d''achat',
  `etat_ex` varchar(20) NOT NULL COMMENT 'état (neuf, bon, moyen, médiocre, a changer',
  `fk_id_li` int(8) unsigned NOT NULL COMMENT 'Clef étrangère (Id du livre correspondant à
  	 l''exemplaire)',
  PRIMARY KEY (`reference_ex`),
  KEY `fk_id_li` (`fk_id_li`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des exemplaires de livres en circulation';

CREATE TABLE IF NOT EXISTS `livres` (
  `id_li` int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id du livre',
  `titre_li` varchar(255) NOT NULL COMMENT 'titre du livre',
  `annee_parution_li` varchar(20) NOT NULL COMMENT 'année de première parution',
  `presentation_li` text NOT NULL COMMENT 'présentation sommaire du livre',
  PRIMARY KEY (`id_li`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table des livres' AUTO_INCREMENT=1;

–- 
–- Enfin, les directives qui suivent permettent de définir dans les tables 'auteurs_livres', 'emprunts'
-– et 'exemplaires' les champs qui sont des clefs étrangères (mots clefs 'ADD CONSTRAINT' et
– 'FOREIGN KEY'.
--

ALTER TABLE `auteurs_livres`
  ADD CONSTRAINT `auteurs_livres_ibfk_2` FOREIGN KEY (`fk_id_li`) REFERENCES `livres` (`id_li`),
  ADD CONSTRAINT `auteurs_livres_ibfk_1` FOREIGN KEY (`fk_id_au`) REFERENCES `auteurs` (`id_au`);

ALTER TABLE `emprunts`
  ADD CONSTRAINT `emprunts_ibfk_2` FOREIGN KEY (`fk_reference_ex`) REFERENCES `exemplaires` (`reference_ex`),
  ADD CONSTRAINT `emprunts_ibfk_1` FOREIGN KEY (`fk_id_ab`) REFERENCES `abonnes` (`id_ab`);

ALTER TABLE `exemplaires`
  ADD CONSTRAINT `exemplaires_ibfk_1` FOREIGN KEY (`fk_id_li`) REFERENCES `livres` (`id_li`);
				
REMARQUES:
  • Ce programme crée la STRUCTURE de la BD et non son contenu. Les différents champs sont créés à leurs valeurs par défaut. Ce programme est donc représentatif du M.P.D de la base de données "bibliothèque" telle qu'elle est définie par le MLD du chapitre IV;
  • Cette structure de base de données peut être créée de deux façons:
    • Soit en transmettant les requêtes depuis une application utilisatrice en utilisant l'A.P.I MySQL;
    • Soit en utilisant les commandes supportées par l'IHM associé au SGBD : dans ce cas, les commandes passées via l'IHM engendrent les mêmes requêtes SQL et les transmettent au moteur de base de données du SGBD.
    • En général, l'IHM permet de visualiser les requêtes SQL qu'il produit lors de chaque commande. Le code SQL étudié ci-dessus est le code engendré par l'IHM du SGD MySQL lorsqu'on crée la base de données 'bibiliotheque";
    • Très souvent, l'état initial de la base de données est créé par l'intermédiaire de l'IHM, les évolutions ultérieures du contenu et de la structure de la BD étant gérées dynamiquement par l'application utilisatrice.

VI.3.7.EXEMPLE N° 6 - Utilisation d'une table de jonction du MLD (jointure de tables):

Dans la base de données "bibliotheque", définie plus haut, nous avons les tables suivantes:
  • auteurs ( id_au, nom_au, prenoms_au, biographie_au );
  • auteurs_livres ( fk_id_au, fk_id_li ) ; // Table de jonction de l'association auteurs - (ecrire) - livres;
  • livres ( id_li, titre_li, annee_parution_li, presentation_li );
Nous voulons lister tous les livres écrits par un auteur donné avec leur texte de présentation, par ordre alphabétique croissant du titre des livres. Pour cela, nous allons effectuer la jointure de ces trois tables dans l'ordre où elles apparaissent dans la liste ci-dessus, en ne gardant dans la jointure que les colonnes donnant les noms et prénoms des auteurs, les titres de livres et la présentation des livres.
Nous supposerons que le nom et les prénoms de l'auteur ont été saisis préalablement dans les variables $nom et $prenoms:
// Connexion au SGBD ( URL, Nom, Mot de passe )
mysql_connect( "localhost:3306","MonIdClient","MonMotDePasse");

// Sélection de la base de données
mysql_select_db( 'bibliotheque' );

// Création de la requête de jointure des table auteurs, auteurs_livres et livres:
$Requete =
"SELECT id_au, livres.titre_li, livres.presentation_li FROM auteurs
INNER JOIN auteurs_livres ON auteurs.id_au = auteurs_livres.fk_id_au
INNER JOIN livres ON livres.id_li = auteurs_livres.fk_id_li WHERE nom_au = $nom AND prenoms_au = $prenoms
ORDER BY livres.titre_li ASC";

// Envoi de la requête de jointure au SGBD
$R = mysql_query( $Requete );

// Récupération des valeurs sélectionnées et affichage des résultats
while ( ( $Ligne = mysql_fetch_array($R) ) != false )
{
echo "<br />-".titre_li." ".Présentation : ".presentation_li;
} echo "
" ;
// Clôture de la connexion au SGBD
mysql_close();


Retour accès aux cours Retour sommaire cours
FormateurGaucheRepos FormateurGaucheActif FormateurDroitRepos FormateurDroitActif