Le NOT NULL dans la création de table Internaute indique que l’attribut correspon-dant doit toujours avoir une valeur.. Une autre manière de forcer un attribut à toujours prendre une val
Trang 1Le langage utilisé est la partie de SQL qui concerne la définition des données –
le Langage de Définition de Données ou LDD Il existe plusieurs versions de SQL Le
plus ancien standard date de 1989 Il a été révisé de manière importante en 1992 La norme résultant de cette révision, à laquelle se conforme MySQL, est SQL 92, SQL2
ou SQL ANSI MySQL propose des extensions à la norme, mais nous allons nous fixer pour but de développer un site compatible avec tous les SGBD relationnels,
ce qui amène à éviter ces extensions Une discussion consacrée à la portabilité sur différents SGBD est proposée page 233.
4.3.1 Tables
La commande principale est CREATE TABLE que nous avons déjà rencontrée Voici
la commande de création de la table Internaute.
CREATE TABLE I n t e r n a u t e ( e m a i l VARCHAR ( 4 0 ) NOT NULL,
nom VARCHAR ( 3 0 ) NOT NULL , prenom VARCHAR ( 3 0 ) NOT NULL,
m o t _ d e _ p a s s e VARCHAR ( 3 2 ) NOT NULL,
a n n e e _ n a i s s a n c e INTEGER) ;
La syntaxe se comprend aisément La seule difficulté est de spécifier le type de chaque attribut MySQL propose un ensemble très riche de types, proche de la norme SQL ANSI Nous nous limiterons à un sous-ensemble, suffisant pour la grande majorité des applications, présenté dans le tableau 4.14 Entre autres bonnes raisons
de ne pas utiliser tous les types de MySQL, cela permet de rester compatible avec les
autres SGBD À l’exception de TEXT, les types mentionnés dans le tableau 4.14 sont connus de tous les SGBD relationnels.
Tableau 4.14 — Les principaux types de données SQL
Type Description
CHAR(n) Une chaîne de caractères de longueur fixe égale àn INTEGER Un entier.
VARCHAR(n) Une chaîne de caractères de longueur variable d’au plusn DECIMAL(m,n) Un numérique surm chiffres avecn décimales.
DATE Une date, avec le jour, le mois et l’année.
TIME Un horaire, avec heure, minutes et secondes.
TEXT Un texte de longueur quelconque.
Le NOT NULL dans la création de table Internaute indique que l’attribut correspon-dant doit toujours avoir une valeur Une autre manière de forcer un attribut à toujours prendre une valeur est de spécifier une valeur par défaut avec l’option DEFAULT.
CREATE TABLE N o t a t i o n ( i d _ f i l m INTEGER NOT NULL,
e m a i l VARCHAR ( 4 0 ) NOT NULL,
n o t e INTEGER DEFAULT 0 ) ;
Trang 24.3.2 Contraintes
La création d’une table telle qu’on l’a vue précédemment est assez sommaire car elle n’indique que le contenu de la table sans spécifier les contraintes que doit respecter
ce contenu Or il y a toujours des contraintes et il est indispensable de les inclure dans
le schéma pour assurer, dans la mesure du possible, l’intégrité de la base.
Voici les règles – ou contraintes d’intégrité – que l’on peut demander au système de
garantir :
1 un attribut doit toujours avoir une valeur ;
2 un attribut (ou un ensemble d’attributs) constitue(nt) la clé de la table ;
3 un attribut dans une table est lié à la clé primaire d’une autre table (intégrité référentielle) ;
4 la valeur d’un attribut doit être unique au sein de la table ;
5 un attribut ne peut prendre ses valeurs que parmi un ensemble prédéfini Les contraintes sur les clés doivent être systématiquement spécifiées.
Contrainte NOT NULL
Il peut arriver que la valeur d’un attribut soit inconnue : on dit dans ce cas qu’elle est « à NULL » NULL n’est pas une valeur mais une absence de valeur ce qui est très différent d’une valeur « blanc » ou « 0 » Conséquences :
1 on ne peut pas faire d’opération incluant un NULL ;
2 on ne peut pas faire de comparaison avec un NULL.
L’option NOT NULL oblige à toujours indiquer une valeur On peut ainsi demander
à MySQL de garantir que tout internaute a un mot de passe.
mot_de_passe VARCHAR(60) NOT NULL
MySQL rejettera alors toute tentative d’insérer une ligne dans Internaute sans
donner de mot de passe Si les valeurs à NULL sont autorisées, il faudra en tenir compte quand on interroge la base Cela peut compliquer les choses, voire donner des résultats surprenants : forcez vos attributs important à avoir une valeur.
Clés d’une table
Il peut y avoir plusieurs clés dans une table, mais l’une d’entre elles doit être choisie
comme clé primaire Ce choix est important : la clé primaire est la clé utilisée pour
référencer une ligne et une seule à partir d’autres tables Il est donc assez délicat de la remettre en cause après coup En revanche, les clés secondaires peuvent être créées
ou supprimées beaucoup plus facilement La clé primaire est spécifiée avec l’option PRIMARY KEY.
CREATE TABLE I n t e r n a u t e ( e m a i l VARCHAR ( 4 0 ) NOT NULL,
nom VARCHAR ( 3 0 ) NOT NULL ,
Trang 3prenom VARCHAR ( 3 0 ) NOT NULL,
m o t _ d e _ p a s s e VARCHAR ( 3 2 ) NOT NULL,
a n n e e _ n a i s s a n c e INTEGER,
PRIMARY KEY ( e m a i l ) ) ;
Il devrait toujours y avoir une PRIMARY KEY dans une table pour ne pas risquer d’insérer involontairement deux lignes strictement identiques Une clé peut être constituée de plusieurs attributs :
CREATE TABLE N o t a t i o n ( i d _ f i l m INTEGER NOT NULL,
e m a i l VARCHAR ( 4 0 ) NOT NULL,
n o t e INTEGER NOT NULL, PRIMARY KEY ( i d _ f i l m , e m a i l ) ) ;
Tous les attributs figurant dans une clé doivent être déclarés NOT NULL Cela n’a pas vraiment de sens en effet d’identifier des lignes par des valeurs absentes Certains SGBD acceptent malgré tout d’indexer des valeurs nulles, mais MySQL le refuse.
On peut également spécifier que la valeur d’un attribut est unique pour l’ensemble
de la colonne Cela permet d’indiquer des clés secondaires On peut ainsi indiquer que
deux artistes ne peuvent avoir les mêmes nom et prénom avec l’option UNIQUE.
CREATE TABLE A r t i s t e ( i d INTEGER NOT NULL,
nom VARCHAR ( 3 0 ) NOT NULL, prenom VARCHAR ( 3 0 ) NOT NULL,
a n n e e _ n a i s s a n c e INTEGER,
PRIMARY KEY ( i d ) , UNIQUE ( nom , prenom ) ) ;
Il est facile de supprimer cette contrainte de clé secondaire par la suite Ce serait beaucoup plus difficile si on avait utilisé la paire (nom, prenom) comme clé primaire, puisqu’elle serait alors utilisée pour référencer un artiste dans d’autres tables.
La clé de la table Artiste est un numéro qui doit être incrémenté à chaque
insertion On pourrait utiliser l’option AUTO_INCREMENT, mais elle est spécifique à MySQL, ce qui empêcherait l’utilisation de notre application avec d’autres SGBD.
Le site utilise un générateur d’identifiant décrit dans la section consacrée à la portabilité, page 233 Si vous ne vous souciez pas de compatibilité, l’utilisation de AUTO_INCREMENT, décrite page 72, est tout à fait appropriée.
Clés étrangères
La norme SQL ANSI permet d’indiquer les clés étrangères dans une table, autrement dit, quels sont les attributs qui font référence à une ligne dans une autre table On peut spécifier les clés étrangères avec l’option FOREIGN KEY.
CREATE TABLE F i l m ( i d INTEGER NOT NULL,
t i t r e VARCHAR ( 5 0 ) NOT NULL,
annee INTEGER NOT NULL,
i d _ r e a l i s a t e u r INTEGER,
g e n r e VARCHAR( 3 0 ) NOT NULL,
Trang 4r e s u m e TEXT , / ∗ LONG p o u r ORACLE ∗ /
c o d e _ p a y s VARCHAR ( 4 ) , PRIMARY KEY ( i d ) ,
FOREIGN KEY ( i d _ r e a l i s a t e u r ) REFERENCES
A r t i s t e ,
FOREIGN KEY ( c o d e _ p a y s ) REFERENCES P a y s ) ;
La commande
FOREIGN KEY (id_realisateur) REFERENCES Artiste
indique qu’id_realisateur référence la clé primaire de la table Artiste En
prin-cipe MySQL devrait vérifier, pour toute modification pouvant affecter le lien entre les deux tables, que la valeur de id_realisateur correspond bien à une ligne d’Artiste Ces modifications sont :
1 l’insertion dans Film avec une valeur inconnue pour id_realisateur ;
2 la destruction d’un artiste ;
3 la modification d’id dans Artiste ou d’id_realisateur dans Film.
En d’autres termes le lien entre Film et Artiste est toujours valide Cette contrainte
est importante pour garantir qu’il n’y a pas de fausse référence dans la base, par exemple qu’un film ne fait pas référence à un artiste qui n’existe pas Il est beaucoup plus confortable d’écrire une application par la suite quand on sait que les informa-tions sont bien là ó elles doivent être.
REMARQUE –MySQL accepte toujours la clause FOREIGN KEY, mais n’applique les contraintes définies par cette clause que quand la table est créée avec le typeInnoDB InnoDB est un module de stockage et de gestion de transaction qui peut être utilisé optionnellement Par défaut, MySQL crée des tables dont le type, MyISAM, est celui de son propre moteur de stockage, lequel ne reconnaỵt ni clés étrangères, ni transactions.
Énumération des valeurs possibles
La norme SQL ANSI comprend une option CHECK (condition ) pour exprimer des
contraintes portant soit sur un attribut, soit sur une ligne La condition elle-même peut être toute expression suivant la clause WHERE dans une requête SQL Les contraintes les plus courantes sont celles consistant à restreindre un attribut à un ensemble de valeurs, mais on peut trouver des contraintes arbitrairement complexes, faisant référence à d’autres relations.
Voici un exemple simple qui restreindrait, en SQL ANSI, les valeurs possibles des
attributs annee et genre dans la table Film.
CREATE TABLE F i l m ( i d INTEGER NOT NULL,
t i t r e VARCHAR ( 5 0 ) NOT NULL,
annee INTEGER NOT NULL CHECK ( annee BETWEEN 1890 AND 2 1 0 0 ) NOT NULL,
i d _ r e a l i s a t e u r INTEGER,
Trang 5CHECK ( g e n r e IN ( ’ H i s t o i r e ’ , ’ Western ’ , ’
Drame ’ ) ) ,
r e s u m e TEXT , / ∗ LONG p o u r ORACLE ∗ /
c o d e _ p a y s VARCHAR ( 4 ) , PRIMARY KEY ( i d ) ,
FOREIGN KEY ( i d _ r e a l i s a t e u r ) REFERENCES
A r t i s t e ,
FOREIGN KEY ( c o d e _ p a y s ) REFERENCES P a y s ) ;
Comme pour les clés étrangères, MySQL accepte la clause CHECK mais ne traite pas la contrainte qu’elle définit Il n’est pas non plus possible d’obtenir la contrainte définissant un intervalle pour les années.
Une autre manière de définir, dans la base, l’ensemble des valeurs autorisées pour un attribut –en d’autres termes, une codification imposée– consiste à placer ces valeurs dans une table et la lier à l’attribut par une contrainte de clé étrangère C’est
ce que nous avons fait par exemple pour la table Pays.
CREATE TABLE P a y s ( c o d e VARCHAR( 4 ) NOT NULL,
nom VARCHAR ( 3 0 ) DEFAULT ’ I nconnu ’ NOT NULL,
l a n g u e VARCHAR ( 3 0 ) NOT NULL,
PRIMARY KEY ( c o d e ) ) ; INSERT INTO P a y s ( code , nom , l a n g u e )
VALUES ( ’ FR ’ , ’ F r a n c e ’ , ’ F r a n ç a i s ’ ) ;
INSERT INTO P a y s ( code , nom , l a n g u e )
VALUES ( ’USA ’ , ’ E t a t s Unis ’ , ’ A n g l a i s ’ ) ;
INSERT INTO P a y s ( code , nom , l a n g u e )
VALUES ( ’ IT ’ , ’ I t a l i e ’ , ’ I t a l i e n ’ ) ;
Comme MySQL n’associe pas de vérification automatique à la commande FOREIGN KEY (du moins avec le type de tables par défaut), il faut faire cette vérification dans l’application, et notamment, comme nous le verrons, au niveau de l’interface qui permet de saisir les données.
Création de la base
Le fichierFilms.sqldonne le script complet de création de la base Films À l’exception
du type TEXT pour le résumé, les commandes sont conformes au SQL ANSI.
Exemple 4.1 webscope/installation/Films.sql: Script de création de la base Films.
/ ∗ Commandes d e c r é a t i o n d e l a b a s e F i l m s
SQL ANSI SAUF l e t y p e TEXT ( r e m p l a c e r p a r LONG p o u r ORACLE) ∗ /
CREATE TABLE I n t e r n a u t e ( e m a i l VARCHAR ( 4 0 ) NOT NULL,
nom VARCHAR ( 3 0 ) NOT NULL , prenom VARCHAR ( 3 0 ) NOT NULL,