Analyse et Conception de Systèmes Informatiques (ACSI)
2 Cours 1 : Présentation L'algèbre relationnelle Le modèle entité-relation (E-A) Cours 2 : Du modèle E-A au MPD Le langage SQL Cours 3 : SQL avancé Cours 4 : Méthodes de modélisation Cours 5 : Administration et sécurité
3 SQL Avancé L'intégrité référentielle Les jointures Les groupements Les transactions L'accès à la base depuis un autre langage
4 L'intégrité référentielle Rappel : Dans un modèle physique de données, les tables sont liés entre elles par le biais d'une clé étrangère. La clé étrangère d'une table permet de lier la table à la clé primaire de l'autre table. Lors de la sélection des données, l'association entre les deux tables est effectuée grâce à une jointure entre ces deux tables.
5 L'intégrité référentielle Exemple : Ici, chaque référence à une adresse est respectée. Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
6 L'intégrité référentielle Exemple : Si on supprime de la table adresse la ligne 4, il devient impossible de retrouver l'adresse de Marie Durand. Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
7 L'intégrité référentielle Lors de la création des tables, il est possible de confier ce contrôle à la base de données. Le fonctionnement désiré devra être précisé lors de la création des clés externes. Note : Sur MySql, cette fonctionnalité n'est disponible qu'avec le moteur des tables : InnoDB.
8 L'intégrité référentielle Comment garantir qu'une clé trouve toujours la donnée référencée dans la table ? En empêchant la suppression de la table si une référence vers cette donnée existe En supprimant la référence lors de la suppression de la donnée référencée En supprimant automatiquement les données référencées.
9 L'intégrité référentielle L'intégrité référentielle permet de confier à la base le rôle de contrôleur pour qu'une situation comme celle-ci ne puisse pas se produire. Définition : L'intégrité référentielle permet de garantir que toute clé étrangère correspond bien à une clé primaire à laquelle elle fait référence. L'intégrité référentielle est donc un contrôle ajouté à une clé étrangère.
10 L'intégrité référentielle Le moteur de base de données devant effectuer un contrôle lors de chaque suppression ou modification de données, il est indispensable que les clés étrangères soient indexées. Pour assurer un contrôle d'intégrité référentielle, il faut donc créer : Un indexe sur la clé étrangère Une clé étrangère avec lien vers la donnée référencée
11 L'intégrité référentielle Déclarer une référence : Lors d'un create table, il faut ajouter une clause FOREIGN KEY (champ1, […, champN]) REFERENCES table(champ1, […, champN]) ON UPDATE action ON DELETE action
12 L'intégrité référentielle Les actions possibles sont : RESTRICT : si une référence est trouvée, la suppression ou la modification sera interdite. SET NULL : si une référence est trouvée, la suppression ou la modification aura pour effet en plus de l'action de mettre à jour la référence avec la valeur NULL. CASCADE : si une référence est trouvée, la suppression ou la modification aura pour effet en plus de l'action d'effectuer la même opération sur les données trouvées. NO ACTION : pas de contrôle d'intégrité référentielle.
13 L'intégrité référentielle Exemple avec ON UDATE RESTRICT : Ne fonctionnent pas : Update personne set id_adresse = 5 where id = 1 Update adresse set id = 8 where id =3 Insert personne values (5, 'Yu','Van',5) Fonctionnent : Update personne set id_adresse=1 where id=3 Update personne set id_adresse=null where id=1 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
14 L'intégrité référentielle Exemple avec ON UDATE CASCADE : Action : update adresse set id=5 where id=3 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart5 3DuboisJeanNULL 4SimpsonLisa5 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 5742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
15 L'intégrité référentielle Exemple avec ON UDATE CASCADE : Ne fonctionnent pas : Update personne set id_adresse = 5 where id = 1 Insert personne values (5, 'Yu','Van',5) Fonctionnent : Update personne set id_adresse=1 where id=3 Update adresse set id = 8 where id =3 Update personne set id_adresse=null where id=1 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
16 L'intégrité référentielle Exemple avec ON UDATE SET NULL : Action : update adresse set id=5 where id=3 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBartNULL 3DuboisJeanNULL 4SimpsonLisaNULL Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 5742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
17 L'intégrité référentielle Exemple avec ON UDATE SET NULL : Ne fonctionnent pas : Update personne set id_adresse = 5 where id = 1 Insert personne values (5, 'Yu','Van',5) Fonctionnent : Update personne set id_adresse=1 where id=3 Update adresse set id = 8 where id =3 Update personne set id_adresse=null where id=1 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
18 L'intégrité référentielle Exemple avec ON UDATE NO ACTION : Ne fonctionnent pas : Fonctionnent : Update personne set id_adresse = 5 where id = 1 Insert personne values (5, 'Yu','Van',5) Update personne set id_adresse=1 where id=3 Update adresse set id = 8 where id =3 Update personne set id_adresse=null where id=1 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
19 L'intégrité référentielle Exemple avec ON DELETE RESTRICT : Ne fonctionnent pas : Delete adresse where id =3 Fonctionnent : Delete personne where id = 1 Delete adresse where id = 2 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
20 L'intégrité référentielle Exemple avec ON DELETE CASCADE : Action : delete adresse where id=3 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
21 L'intégrité référentielle Exemple avec ON DELETE CASCADE : Ne fonctionnent pas : Fonctionnent : Delete personne where id=3 Delete adresse where id =3 Delete adresse where id =2 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
22 L'intégrité référentielle Exemple avec ON DELETE SET NULL : Action : delete adresse where id=3 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBartNULL 3DuboisJeanNULL 4SimpsonLisaNULL Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
23 L'intégrité référentielle Exemple avec ON DELETE SET NULL : Ne fonctionnent pas : Fonctionnent : Delete personne where id=3 Delete adresse where id =3 Delete adresse where id =2 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
24 L'intégrité référentielle Exemple avec ON DELETE NO ACTION : Ne fonctionnent pas : Fonctionnent : Delete personne where id=3 Delete adresse where id =3 Delete adresse where id =2 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
25 Les jointures (1/13) Les jointures permettent sélectionner les données se trouvant dans plusieurs tables. Il est indispensable de savoir les utiliser car elles permettent de préciser les données sur lesquelles travailler lors d'un : Select (lecture) Update (mise à jour) Delete (suppression)
26 Les jointures (2/13) Principe : Une jointure a lieu entre deux tables. Elles permettent de préciser au moteur SQL par quel critère d'égalité la correspondance doit s'effectuer. Si les données à traiter se trouvent dans trois tables, il sera nécessaire de préciser par quelle égalité ces trois tables vont correspondre;il y aura donc deux clauses à écrire.
27 Les jointures (3/13) Exemple : Pour lire l'adresse correspondant à la personne, il faut écrire : Select * from personne, adresse where personne.adress = adresse.id Adresse IDint Voievarchar(200) CPint Villevarchar(50) IDint Nomvarchar(30) Prenomvarchar(30) Adress#int Personne
28 Les jointures (4/13) Note : Même si l'association des tables est explicité dans la base de données par le biais d'une clé étrangère, il faut toujours indiquer au moteur comment associer les deux tables. Il est impossible d'effectuer une jointure entre deux tables si les champs utilisés ne sont pas d'un type compatible. Si je dois toutefois effectuer cette jointure, il faut convertir l'un des deux champs.
29 Les jointures (5/13) Dans la clause WHERE se mélangent les associations entre les tables et les conditions de sélection des données. Il est important de ne pas les confondre : Select * from personne, adresse where personne.adress = adresse.id and personne.nom = 'Durand'
30 Les jointures (6/13) Select * from personne, adresse where personne.adress = adresse.id and personne.nom = 'Durand' Dans cette requête, personne.adresse = adresse.id permet d'associer les 2 tables. Personne.nom = 'Durand' permet d'ajouter un critère de sélection. L'ordre n'a pas d'importance.
31 Les jointures (7/13) Il existe une autre syntaxe permettant de séparer les clauses dédiées à la jointure des critères de sélection. Cette syntaxe permet également d'effectuer des jointures ouvertes. Jusqu'ici seules les jointures fermées ont été vues. Elles ne permettent que d'associer les données trouvées à la fois dans la première et dans la seconde table. Si l'on cherche à préciser optionnellement des données, il faudra utiliser une jointure ouverte.
32 Les jointures (8/13) Exemple : On désire lire toutes les personnes et accessoirement donner leur adresse si celle-ci est connue. La requête : Select * from personne, adresse where personne.adress = adresse.id ne retournera pas les personnes n'ayant pas d'adresse référencée.
33 Les jointures : inner join L'association se fait directement entre les tables en précisant les colonnes concernées. Select * from table1 INNER JOIN table2 on table1.cle_primaire = table2.cle_etrangere Exemple : Select * from personne, adresse where personne.adress = adresse.id Select * from personne INNER JOIN adresse on personne.adress = adresse.id
34 Les jointures (10/13) Il existe trois type d'associations : INNER JOIN : jointure fermée, les données doivent être à la fois dans les 2 tables LEFT [OUTER] JOIN : jointure ouverte, on lit les données de la table de gauche en y associant éventuellement celle de la table de droite. RIGHT [OUTER] JOIN : jointure ouverte, on lit les données de la table de droite en y associant éventuellement celle de la table de gauche.
35 Les jointures (11/13) Exemple : Ainsi, pour lire toutes les personnes et accessoirement donner leur adresse si celle-ci est connue. Il faudra écrire : Select * from personne LEFT OUTER JOIN adresse Les personnes pour lesquelles l'adresse n'est pas connue auront les champs de la table adresse à NULL.
36 Les jointures (12/13) Les mots clés LEFT JOIN et RIGHT JOIN diffèrent uniquement dans le sens de lecture. Les 2 requêtes : Select * from personne LEFT OUTER JOIN adresse et Select * from adresse RIGHT OUTER JOIN personne Sont parfaitement identiques.
37 Les jointures (13/13) Exemple avec critère : Select * from personne, adresse where personne.adress = adresse.id and personne.nom = 'Durand' Select * from personne left join adresse on personne.adress=adresse.id where personne.nom = 'Durand'
38 Le groupement Il est possible d'effectuer des opération sur un ensemble de données. Certaines opérations sont : Min (retourne le minimum) Max (retourne le maximum) Count (retourne le nombre) Sum (retourne la somme) Afin de préciser au moteur SQL que cette opération porte sur une sélection de données, il faut préciser la clause GROUP BY.
39 Le groupement Ainsi pour effectuer compter le nombre de fois où une valeur est utilisée on écrira : select champ2, count(champ1) from table 1 group by champ2
40 Le groupement Si l'on désire créer des critères de sélection qui portent sur un ensemble de données, il faudra associer la clause GROUP BY à la clause HAVING (ou NOT HAVING). Exemple, on désire sélectionner les données dont le nombre de répétition est supérieur à N. Select * from table1 group by champ2 having count(champ2)>N
41 Le groupement Exemple : On désire connaître le nombre de personne vivant à chaque adresse : select adresse.voie, adresse.cp, adresse.ville, count(1) from personne left join adresse on personne.id_adresse = adresse.id Group by id_adresse Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
42 Le groupement Exemple : On désire sélectionner les adresses ayant au moins 2 occupants : select adresse.voie, adresse.cp, adresse.ville from personne, adresse where personne.id_adresse = adresse.id Group by id_adresse having count(1)>1 Personne IdNomPrenomId_adresse 1DurandMarie4 2SimpsonBart3 3DuboisJeanNULL 4SimpsonLisa3 Adresse IdVoieCPVille 11, rue Ici75002Paris 212, rue labas 75015Paris 3742 Evergreen Terrasse Springfield 4Chemin perdu 66000Perpignan
43 Les transactions Lors de la modifications ou la suppression de données dans plusieurs tables, il est souvent utile de s'assurer que les mises à jour seront effectuées partout. En mode, classique, les requêtes s'enchaînent. La première peut fonctionner alors que la suivante peut rencontrer une erreur. La base de données contient alors des données dans certaines tables et pas dans d'autres.
44 Les transactions Pour ouvrir une transaction, il faut utiliser la commande : START TRANSACTION. Les différentes commandes de mise à jour ou de suppression sont ensuite transmises. Enfin deux commandes permettent de fermer la transaction : - COMMIT TRANSACTION pour confirmer - ROLLBACK TRANSACTION pour annuler
45 Les transactions Afin de palier à ce problème, il est possible d'utiliser des transactions. Une transaction permet d'effectuer des opération en mode hypothétique sur la base. Ce n'est que lorsque l'ordre de confirmation (ou d'annulation) sera transmis que les modifications (ou non) prendront effet sur la base de données.
46 Les transactions Attention : lorsqu'une modification sur une table est en cours, les données sont verrouillées en lecture et en écriture. Il est possible de rencontrer des situation de verrouillages mutuels entre deux transactions : les dead-lock. Dans ce cas, le système de base de données le repère et émet automatiquement un rollback sur l'une des transactions en cours d'exécution.
47 L'accès à la base depuis un autre langage de programmation Il est possible d'accéder à la base données depuis d'autres langages de programmation. Il est possible d'accéder à la base : Par des API correspondant à la base Par des connecteurs standardisés (ODBC) Les API sont des librairies écrites dans le langage de programmation correspondant proposant des fonctions prêtes à l'emploi pour la base données concernée. ODBC est un outil Microsoft établissant un standard pour toutes les bases de données.
48 L'accès à la base depuis PHP Afin de communiquer avec une base données MySQL, PHP propose des fonctions prêtes à l'emploi. Elles serviront notamment à : Se connecter à la base (et se déconnecter) Soumettre des requêtes SQL Lire les résultats
49 L'accès à la base depuis PHP Pour se connecter, il faut : $id=mysql_connect("Adresse_bd","Login","MDP") If faut ensuite préciser la base sur laquelle travailler : mysql_select_db("Nom_bd"); Enfin, il ne faut pas oublier de se déconnecter : mysql_close($id);
50 L'accès à la base depuis PHP Pour transmettre une requête au serveur : $result=mysql_query("requête",$id); Pour demander les résultats : $row = mysql_fetch_row($result)) Note : les résultats sont transmis ligne à ligne par le serveur. Il est donc nécessaire de boucler pour tout récupérer. La variable $row est un tableau dont la dimension est égale au nombre de champ demandé.
51 L'accès à la base depuis PHP Exemple, on veut afficher les nom, prénom des personnes et leur adresse : $id=mysql_connect("localhost","login","mdp") ; mysql_select_db("gens"); $sql="select p.nom, p.prenom, a.voie, a.cp, a.ville from personne p, adresse a WHERE p.id_adresse = a.id" ; $result=mysql_query($sql,$id); while($row = mysql_fetch_row($result)){ echo $row[0].' '.$row[1].' : '.$row[2].' '.$row[3].' '.$row[4]; } mysql_close($id);