<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "/usr/local/share/xml/docbook/4.2/docbookx.dtd">
<article class="techreport" lang="fr">

  <!--  ================================= Entetes info ============================= -->
  <articleinfo>
    <author>
      <firstname>Ivan</firstname>
      <surname>Kurzweg</surname>  
      <email>ik-r@wanadoo.fr</email>
    </author>

    <title>Initiation à MySQL</title>

    <copyright>
      <year>20067</year>
      <holder>Ivan KURZWEG, <emphasis>ik-r@wanadoo.fr</emphasis></holder>
    </copyright>

    <legalnotice>
      <para>Permission to use, copy, modify, and distribute this documentation for any purpose with or without fee is here by granted, provided that the above copyright notice and this permission notice appear in all copies.
</para>        
    </legalnotice>

    <keywordset>
      <keyword>Html, css, cours, initiation logiciel libre, </keyword>
    </keywordset>

  </articleinfo>
  
  <abstract> 
    <para>Ce document propose une initiation à l'utilisation de bases de données relationnelles sous MySQL. Nous allons tout d'abord étudier la création et la gestion d'une base de données MySQL en utilisant l'outil PhpMyAdmin. Nous verrons ensuite le langage SQL. Pour finir, une introduction à la modélisation des données vous est proposé, pour vous donner des pistes sur la manière de concevoir une base de données relationnelle.</para>
  </abstract>










  

  <!--  ================================= Chapitre 2 ============================= -->
  <sect1>
    <title>PhpMyAdmin et MySQL </title>  
    <sect2>
      <title>Introduction</title>
      <sect3><title>MySQL</title>
	<para>MySQL est un serveur de bases de données relationnelles <acronym>SQL</acronym> développé dans un souci de performances élevées. Il est multi-thread, multi-utilisateurs. C'est un logiciel libre développé sous double licence en fonction de l'utilisation qui en est faite : dans un produit libre (open-source) ou dans un produit propriétaire. Dans ce dernier cas, la licence est payante, sinon elle est libre.
     </para>
	<para>MySQL est l'oeuvre d'une société suédoise, MySQL AB, fondée par David Axmark, Allan Larsson et Michael Widenius. Le nom MySQL vient de leur habitude à préfixer par « My » une grande partie de leurs dossiers, bibliothèques et outils. La fille de Michael Widenius était surnommée « My ».</para>
	<para>La première version de MySQL est apparue le 23 mai 1995. Il a d'abord été créé pour un usage personnel à partir de mSQL en s'appuyant sur le langage de bas niveau ISAM qu'ils trouvaient trop lent et trop rigide. Ils ont créé une nouvelle interface SQL en gardant la même API que mSQL. MySQL est passé en licence GPL à partir de la version 3.23.19 (juin 2000)</para>
      </sect3>


      <sect3><title>Introduction</title>
	<para>
PhpMyAdmin est l'une des plus célèbres interfaces pour gérer une base de données MySQL sur un serveur PHP. De nombreux hébergeurs, qu'ils soient gratuits ou payants, le proposent ce qui permet à l'utilisateur de ne pas avoir à l'installer. </para><para>
Cette interface pratique permet d'exécuter, très facilement et sans grandes connaissances dans le domaine des bases de données, de nombreuses requêtes comme les créations de table de données, les insertions, les mises à jour, les suppressions, les modifications de structure de la base de données. Ce système est très pratique pour sauvegarder une base de données sous forme de fichier .sql et ainsi transférer facilement ses données. De plus celui-ci accepte la formulation de requêtes SQL directement en langage SQL, cela permet de tester ses requêtes par exemple lors de la création d'un site et ainsi de gagner un temps précieux.
   <figure>
	    <title>Accueil de PhpMyadmin</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma1.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
     </para>
      </sect3>
    </sect2>
    <sect2>
      <title>Création d'une base de données</title>
      <sect3><title>Définition</title>
	<para>
Une base de données, usuellement abrégée en<abbrev> BD</abbrev> ou <abbrev>BDD</abbrev>, est un ensemble structuré et organisé permettant le stockage de grandes quantités d'informations afin d'en faciliter l'exploitation (ajout, mise à jour, recherche de données). Une base de données se traduit physiquement par un ensemble de fichiers sur disque. Le serveur MySQL est capable de gérer simultanément plusieurs bases de données, accessibles en concurrence (des mécanismes tels que les <emphasis>transactions</emphasis> permettent de gérer les problèmes qui en découlent) par une ou plusieurs applications. </para>
	<para>De manière générale, une applications Web est liée à une base de données. Dans notre cas, nous allons créer une base de données consacrée à la gestion d'un magasin de location de planches à voile. Nous allons l'appeler location_planche. Cette base de données stockera différentes informations sur des planches à voiles, des clients et des locations.</para>
      </sect3>
      <sect3><title>Création des tables</title>
	<para>
L'aspect<emphasis> "relationnel"</emphasis> des SGBDR est caractérisé en partie par la possibilité de regrouper dans un même fichier des données hétérogènes. Ce qui semble naturel aujourd'hui, alors que l'idée paraissait saugrenue dans les années 1970. L'idée des tables est donc d'abstraire la notion de fichiers, et de définir tout simplement ce que contiendra chaque<emphasis> enregistrement</emphasis> de la table. Nous verrons en fin de cours une méthode pour arriver à se représenter les tables à créer, mais pour l'instant, contentons nous de créer deux tables : <filename>PLANCHES</filename> et <filename>CLIENTS</filename>. La tables PLANCHES contiendra pour le moment un seul champ (une seule donnée par enregistrement) : <filename>PLA_NUM</filename>. La table CLIENTS contiendra un seul champ, <filename>CLI_NUM</filename>.
    
   <figure>
	    <title>Création d'une table sous PhpMyAdmin</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma2.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
   <figure>
	    <title>Reqête de création de la table</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma3.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
 </para>
	<note>
	  <para>Vous noterez les conventions de nommage (non obligatoires mais fortement recommandées). Elles peremettent de retrouver rapidement à quelle table appartient une données (un PRENOM peut appartenir à plusieurs tables : CLIENTS, EMPLOYES, ..)</para></note>
      </sect3>      
      <sect3><title>Identifiants</title>
	<para>
Dans les exemples précédents, nous avons limité le contenu de chacune des tables à un seul champ. Nous avons néanmoins pris soin de préciser que les champs "numéros" de chaque table étaient des <emphasis>clefs primaires</emphasis> aussi appelés <emphasis>identifiants</emphasis>. Cette propriété particulière implique que tout enregistrement de la table peut être identifié de manière unique par ce champ, c'est-à-dire qu'à <emphasis>une valeur</emphasis> de l'identifiant ne correspond qu'<emphasis>un seule enregistrement</emphasis> de la table. Il faut au moins un identifiant par table, et il est préférable pour des raisons de performances qu'il soit un entier.
     </para>
	<para>
Il est également intéressant de noter que nous avons mis le champ <command>extra</command> sur la valeur <command>auto_increment</command>. Ainsi,la clef primaire peut être gérée directement par le serveur MySQL, qui l'incrémentera à chaque nouvel ajout dans la table. 
</para>
      </sect3>
      <sect3><title>Type de donnéees</title>
	<para>
Pour le moment, nos tables ne contiennent pas beaucoup de champs ! Nous allons rajouter quelques informations complémentaires. A chaque nouveau champ, nous allons devoir choisir un type de données, c'est-à-dire spécifier quelles valeurs pourront être stockées dans ces champs. Pour la table <filename>PLANCHES</filename>, nous allons ajouter les champs suivants : 
<itemizedlist>
	    <listitem>
	      <para><command>PLA_MODELE : CHAR(20)</command> </para></listitem>
	    <listitem>
	      <para><command>PLA_MARQUE : CHAR (20)</command></para></listitem>
	    <listitem>
	      <para><command>PLA_POIDS : FLOAT</command></para></listitem>
	    <listitem>
	      <para><command>PLA_ANNEE : INTEGER</command></para></listitem></itemizedlist>
     </para>
	<para>Pour la table client nous allons ajouter les champs suivants :
<itemizedlist>

	    <listitem>
	      <para><command>CLI_NOM : CHAR (20)</command></para></listitem>
	    <listitem>
	      <para><command>CLI_PRENOM : CHAR(20)</command></para></listitem>
	    <listitem>
	      <para><command>CLI_TEL : CHAR(10)</command></para></listitem>
	    <listitem>
	      <para><command>CLI_ADR : VARCHAR(150)</command></para></listitem></itemizedlist>
     </para>


	<para><emphasis role="bold">MySQL</emphasis> supporte un grand
          nombre de types de données, mais voici les plus couramment utilisés : </para>
	

	<sect4>
	  <title>Types numériques</title>

	  <para>Le tableau ci-dessous cite les différents types de données
            numériques sous MySQL. <command>M</command> indique la taille d'affichage, et <command>D</command>
            (valable pour les nombres en virgule flottante), représente le
            nombre de chiffres après la virgule.</para>

	  <table>
	    <title>Types numériques sous MySQL</title>

	    <tgroup cols="3">
	      <tbody>
		<row>
		  <entry><emphasis role="bold">Type</emphasis></entry>

		  <entry><emphasis role="bold">De</emphasis></entry>

		  <entry><emphasis role="bold">1</emphasis></entry>
		</row>

		<row>
		  <entry><emphasis>TINYINT(M)</emphasis></entry>

		  <entry>-128</entry>

		  <entry>127</entry>
		</row>

		<row>
		  <entry><emphasis>SMALLINT(M)</emphasis></entry>

		  <entry>-32768</entry>

		  <entry>32767</entry>
		</row>

		<row>
		  <entry><emphasis>MEDIUMINT(M)</emphasis></entry>

		  <entry>-8388608</entry>

		  <entry>8388607</entry>
		</row>

		<row>
		  <entry><emphasis>INT(M)</emphasis></entry>

		  <entry>-2147483648</entry>

		  <entry>2147483647</entry>
		</row>

		<row>
		  <entry><emphasis>BIGINT(M)</emphasis></entry>

		  <entry>-9223372036854775808</entry>

		  <entry>9223372036854775807</entry>
		</row>

		<row>
		  <entry><emphasis>FLOAT[(M,D)]</emphasis></entry>

		  <entry>-3.402823466E+38</entry>

		  <entry>3.402823466E+38</entry>
		</row>

		<row>
		  <entry><emphasis>DOUBLE[(M,D)]</emphasis></entry>

		  <entry>-1.7976931348623157E+308</entry>

		  <entry>1.7976931348623157E+308</entry>
		</row>
	      </tbody>
	    </tgroup>
	  </table>
	</sect4>

	<sect4>
	  <title>Types Date et heure</title>

	  <itemizedlist>
	    <listitem>
	      <para>Type <command>TIME</command> : MySQL lit et affiche les
                colonnes de type <emphasis>TIME</emphasis> au format
                'HH:MM:SS'. Les valeurs TIME non valides sont transformées en
                date zéro '00:00:00'</para>
	    </listitem>

	    <listitem>
	      <para>Type <command>DATE</command> : Le type
                <emphasis>DATE</emphasis> est prévu lorsque vous souhaitez
                stocker une date. MySQL affiche les valeurs de type
                <emphasis>DATE</emphasis> au format '
                <emphasis>AAAA-MM-JJ</emphasis> '. L'intervalle de validité va
                de '1000-01-01' à  '9999-12-31'. Les dates non valides sont
                transformées en "0000-00-00"</para>
	    </listitem>

	    <listitem>
	      <para>Type <command>DATETIME</command> : Le type
                <emphasis>DATETIME</emphasis> est prévu lorsque vous souhaitez
                stocker une date et une heure. MySQL affiche les valeurs de
                type <emphasis>DATETIME</emphasis> au format '
                <emphasis>AAAA-MM-
JJ HH:MM:SS</emphasis>'</para>
	    </listitem>

	    <listitem>
	      <para>Type <command>TIMESTAMP</command> : Le type
                <emphasis>TIMESTAMP</emphasis> est prévu pour stocker
                automatiquement l'heure courante lors d'une commande
                <emphasis>INSERT</emphasis> ou <emphasis>UPDATE</emphasis> .
                Si vous avez plusieurs colonnes de type
                <emphasis>TIMESTAMP</emphasis> , seule la première colonne
                sera mise à  jour automatiquement.</para>
	    </listitem>
	  </itemizedlist>
	</sect4>


        <sect4>
          <title>Chaînes de caractères</title>

          <para>Les types chaînes sont <command>CHAR , VARCHAR ,
          TEXT</command> . Il en existe d'autres, mais nous nous intéresserons
          en priorité à  ceux-ci.</para>

          <para>Ces types de données vous permettent de définir des chaînes de
          longueur comprise entre 1 et 255 caractères.</para>

          <para><command>CHAR(L) </command>: dans ce cas, quelque soit la
          longueur effective de la chaîne, elle sera toujours stockés sur un
          nombre d'octets fixe, L. Par exemple, si vous définissez
          <command>CHAR (10)</command> et que vous entrez la chaîne "Bonjour",
          elle sera complétée par trois espace dans la table.</para>

          <para><command>VARCHAR(L) </command>: dans ce cas, MySQL stocke la
          chaîne, plus un octet définissant la longueur effecctive de
          l'enregistrement. Dans notre exemple "bonjour", cette chaîne
          occupera 7+1 octets dans la base.</para>

          <para><command>TEXT </command>: ce type de données peut en fait être
          considéré comme un <command>VARCHAR</command> de longueur indéfini.
          Il n'y a pas de limitation de taille pour ce type, insensible à  la
          casse. Dans l'absolu, ce sont les capacités du serveur qui
          déterminent la longueur maximale d'un TEXT.</para>
	</sect4>
	
	<para>De plus, il est possible de spécifier pour chaque champ si une valeur est obligatoire ou non en précisant la valeur de<command> NULL / NOT NULL</command>.</para>
	<figure>
	  <title>Table Clients</title>

	  <mediaobject>
	    <imageobject>
	      <imagedata fileref="images/pma4.jpg" />
	    </imageobject>
	  </mediaobject>
	</figure>	<figure>
	  <title>Table Planches</title>

	  <mediaobject>
	    <imageobject>
	      <imagedata fileref="images/pma5.jpg" />
	    </imageobject>
	  </mediaobject>
	</figure>
      </sect3>

    </sect2>

    <sect2>
      <title>Gestion des enregsitrements avec PhpMyAdmin</title>
      <sect3><title>Insertion d'enregsistrement dans une table</title>
	<para>Nous verrons dans les chapitres suivants comment automatiser l'accès aux données des tables depuis des pages Web et le langage Php. Pour le moment, nous continuons à nous intéresser à PhpMyAdmin et ses fonctionnalités. </para>
	<para>En cliquant sur le lien <filename>Insérer</filename> depuis le menu de la tables clients, nous obtenons un formulaire qui nous permet de remplir directement la table. Il est à noter que PhpMyAdmin nous propose d'exécuter un certain nombre de fonctions sur les données que nous allons entrer. En utilisant le formulaire entrez 5 clients dans la base, et 10 planches. Vous trouverez des exemples de modèles sur le site <ulink utl="http://www.vaguesetvents.com/">www.vaguesetvents.com</ulink> dans la section <emphasis>Windsurf</emphasis>.
</para>
	<figure>
	  <title>Insertion d'un client</title>

	  <mediaobject>
	    <imageobject>
	      <imagedata fileref="images/pma6.jpg" />
	    </imageobject>
	  </mediaobject>
	</figure>
	<para>Si l'insertion est validée par MySQL (si les données correspondent à la définition de la table) PhpMyAdmin affiche la requête qu'il a exécutée pour faire l'insertion. Cette requête est écrite en langage <acronym>SQL</acronym>, le langage que nous utiliserons depuis Php pour interroger MySQL. Il peut donc être intéressant de bien noter ces requêtes pour éventuellement s'en inspirer !

 <programlisting width="80">	  
<![CDATA[
INSERT INTO `location_planche`.`CLIENTS` (
`CLI_NUM` ,
`CLI_NOM` ,
`CLI_PRENOM` ,
`CLI_TEL` ,
`CLI_ADR`
)
VALUES (
NULL , UCASE( 'kurzweg' ) , 'ivan', '0262112233', 'St Paul'
), (
NULL , UCASE( 'payet' ) , 'jean', '0262223344', 'Bois de Nèfles St Paul'
);
]]></programlisting></para>
      </sect3>
      <sect3><title>Affichage, modification et suppression d'enregistrements</title>
	<para>PhpMyAdmin nous permet également de modifier les enregistrements contenus dans la table. Pour ceci, le menu <filename>afficher</filename> présente dans un tableau HTML la liste des enregistrements de la table. On remarque de nouveau qu'on nous présente la requête permettant de faire ce traitement.  </para>
	<figure>
	  <title>Insertion d'un client</title>

	  <mediaobject>
	    <imageobject>
	      <imagedata fileref="images/pma7.jpg" />
	    </imageobject>
	  </mediaobject>
	</figure>

      </sect3>
    </sect2>
    <sect2>
      <title>Admministration avec PhpMyAdmin</title>
      <sect3><title>Sauvegarde et restauration</title>
	<para>PhpMyAdmin permet d'exporter et d'importer une base de données, fonctionnalité qui permet ainsi de sauvegarder et de restorer une base, mais aussi de passer d'un environnement de développement à un environnement de production.</para>
	<para>L'exportation permet d'afficher l'ensemble des requêtes SQL nécessaire à la création de la base et à l'insertion des données de manière à retrouver le même état que l'actuel. Il est à noter qu'il est également possible de générer des formats différents (CSV, DOC, PDF, etc ...).</para>
	<para>Pour exporter la base, il faut choisir d'exporter les données et/ou la structure de la base. 
	<figure>
	    <title>Exportation de la base de données</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma8.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>


</para>
	<para>L'opération inverse, l'importation, consiste à exécuter l'ensemble des requêtes SQL qui vont créer la base de données. Il s'agit pour l'administrateur de donner les différentes caractéristiques du fichier à exécuter... </para>
      </sect3>
      <sect3><title>Gestion des utilisateurs</title>
	<para>Il existe dans MySQL la notion d'utilisateur. La création d'utilisateur permet de restreindre les opérations autorisés pour un utilisateur. Par défaut, MySQL ne contient qu'un seul utilisateur, le <emphasis>super-utilisateur</emphasis> <filename>root</filename>. Dans le cas d'applications Web, il peut être intéressant de créer un utilisateur ayant des droits plus limités sur la base de données utilisée. </para>
	<para>Par exemple, il est rare que les pages Web accèdant à une base de données aient besoin de modifier la structure de cette base. Or, les connexions depuis le site Internet se font en utilisant un compte utilisateur. En cas de piratage, il se peut que ce compte soit utilisé pour détruire l'ensemble des données. Nous allons donc prendre l'habitude de créer un utilisateur "web" qui ait des droits plus limités et plus affinés. </para>
	<sect4><title>Création d'un utilisateur</title>
	  <para>Un utilisateur est enregistré au niveau du serveur MySQL, et ses droits sont définis pour chaque base de données hébergée. Le menu "<filename>privilèges</filename>" au niveau de la page d'accueil de PhpMyAdmin permet d'accèder aux différents utilisateurs de MySQL et d'en créer de nouveaux.</para>
	  <figure>
	    <title>Ajout d'un utilisateur</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma9.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
	</sect4>
	<sect4><title>Attribution de privilèges</title>
	  <para>Une fois l'utilisateur créé, il est possible de lui accorder des droits particulier sur une base de données. Dans notre exemple, nous accordons à l'utilisateur <filename>Web</filename> les privilèges suivants sur la base de données <filename>location_planches</filename> : <command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command></para>
	  <figure>
	    <title>Attribution de droits sur une base de données</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma10.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
	</sect4>
      </sect3>
    </sect2>

    <sect2>
      <title>Exercices d'applications</title>
      <para>Dans les cours HTML et Php, nous allons tenter de créer une application permettant de présenter la formation. Au final, toutes les informations devront être extraite d'une base de données. Afin de préparer cette application, nsou allons créer et insérer les données relatives à la formation : 
<orderedlist>
	  <listitem>
	    <para>créez une base de données FORMATION_INITLL.</para></listitem>
	  <listitem>
	    <para>Créez ensuite 3 tables : STAGIAIRES, MODULES, FORMATEUR. Choisissez vous même les champs composant ces tables. Vous prendrez soin de bien choisir les types de données.</para></listitem>
	  <listitem>
	    <para>Insérez ensuite 5 stagiaires, 4 modules et 3 formateurs. </para>
	  </listitem> <listitem>
	    <para>Sauvegardez votre base de données. </para>
	  </listitem>
	  <listitem>
	    <para>Attribuez les bons droits à l'utilisateur web créé dans le cours.  </para>
	  </listitem></orderedlist></para>
    </sect2>
    
    <sect2>
      <title>Tables de jointures</title>
      <para>Notre applications de location de planches contient à présent des clients et des planches à voiles, mais aucune informations sur les locations ! Essayons de trouver une méthode pour représenter le fait qu'un client puisse louer plusieurs fois des planches à voiles ...</para>
      <para>Les données dont nous avons besoin sont les suivantes : quel client a loué quelle planche, à quelle date/heure a débuté la location, et à quelle date/heure a été rendu le matériel ... nous pouvons donc commencer à créer une table location contenant ces données : 
	<figure>
	  <title>Attribution de droits sur une base de données</title>

	  <mediaobject>
	    <imageobject>
	      <imagedata fileref="images/pma11.jpg" />
	    </imageobject>
	  </mediaobject>
	</figure>
Ici, nous avons encore entré un identifiant automatique, que MySQL gérera (<command>auto_increment</command>).
</para>
      <para>Mais il nous manque encore des informations essentielles : les caractéristiques des clients et des planches louées. Ces informations existant déjà dans la base, nous n'allons pas de nouveau les insérer ! En effet, toute modification d'un enregistrement (par exemple un changement de numéro de téléphone) nécessiterait de modifier 2 tables, ce qui peut vite devenir fastidieux .. Nous allons plutôt nous servir des identifiants des autres tables.</para>
      <sect3><title>Clefs étangères</title>
	<para>En effet, nous avons vu que les identifiants ou clefs primaire nous permettent d'accéder de manière unique à un enregistrement d'une table : les <filename>CLI_NUM</filename> sont par exemple des numéros uniques, dont dispose chaque client, et qui permette d'accéder à ses informations. Il suffit donc d'insérer ce numéro dans la table location, pour connaître le numéro du client qui a loué une planche et ainsi pouvoir accéder à ses donnée ! L'insertion d'une clef primaire en provenance d'une autre table s'appelle <emphasis>clef étangère</emphasis>. </para>
	<para>Sous PhpMyadmin, il nous faut d'abord ajouter le champ qui servira de clef étrangère en liaison avec les clients. Ce champ doit être de même type que dans la table CLIENTS, mais ne doit pas être clef primaire de la table LOCATIONS. !
	<figure>
	    <title>Insertion d'un champ complémentaire</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma12.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
</para>
	<para>
Ensuite nous devons dire à MySQL que ce champ <filename>CLI_NUM</filename> est un champ qui est une clef, en utilisant le tableau de PhpMyAdmin <filename>Index</filename>, et le menu <filename>créer une clef sur 1 colonne</filename> : 
	<figure>
	    <title>Création d'un index</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma13.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
<note><para>Le nom de l'index est précédé (c'est une convention) de FK pour <foreignphrase>Foreign Key</foreignphrase>.</para></note>
</para>
	<para>Ensuite, le lien <filename>Gestion des relations</filename> de PhpMyAdmin nous permet de dire que le champ <filename>CLI_NUM</filename> de la table <filename>LOCATIONS</filename> est lié au champ <filename>CLI_NUM</filename> de la table <filename>CLIENTS</filename>. Les menus <filename>ON DELETE</filename> et <filename>ON CASCADE</filename> nous permettent de dire quelles seront les actions à eeffectuer si le champ source est modifié ou mis à jour...</para>
	<para>Il ne nous reste plus qu'à faire la même opération pour le champ <filename>PLA_NUM</filename> ...
</para>
      </sect3>
    </sect2>
    <sect2><title>Relation hiérarchique entre tables</title>
      <para>Dans les paragraphes précédents, nous avons vu comment représenter les locations de planches, en créant une nouvelle table et en ajoutant les clefs étrangères des 2 tables en relation (<filename>CLIENTS</filename> et <filename>PLANCHES</filename>). Cependant, la création d'une table de jointure n'est pas toujours obligatoire... C'est le cas des relations hiérarchiques entre tables, concept que nous préciserons dans le chapitre 3, et qui se caractérise par une relation de type 1,n alors que dans les paragraphes précédents, nous étions plutôt sur des relations de type n,n (un client peut louer <emphasis>plusieurs/n</emphasis> planches, et une planche peut être louée <emphasis>plusieurs/n</emphasis> fois).</para>
      <sect3><title>Modification de la base de données</title>
	<para>Certains clients tiennent absolument à naviguer sur du matériel hawaien ! Or notre base de données ne contient pas ces informations ... Par contre, il nous est facilement possible de retrouver le pays d'origine de chaque marque de planche. Par exemple, les planches de marque Fanatic sont d'origine allemande. Pour intégrer ces nouvelles données, nous avons le choix de modifier la structure de la table <filename>PLANCHES</filename> en rajoutant un champ <filename>PAYS</filename>, et de modifier un par un <emphasis>TOUS</emphasis> les enregistrements ... ou de créer une nouvelle table MARQUES. Prenons la seconde solution ! </para>
<para>La table marque a la structure suivante : 
	<figure>
	    <title>Création d'un index</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma14.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
</para>
	<para>L'information sur la marque dans la table <filename>PLANCHES</filename> est donc redondante. Supprimons le champ<filename> PLA_MARQUE</filename>. 
<figure>
	    <title>Création d'un index</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma15.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
</para>
      </sect3>
      <sect3><title>Ajout de la clef étrangère</title>
	<para>Il nous faut maintenant représenter le fait qu'une planche est d'une certaine marque. Dans notre cas, il nous suffit de remarquer qu'en insérant une clef étrangère dans la tables PLANCHES, qui contiennent le numéro de la marque, il nous sera aisé de retrouver toutes les informations d'une planche, y compris son pays d'origine !</para>
<para>Le principe de création de la clef étrangère est le même que dans les paragraphes précédents : 
<orderedlist>
	    <listitem>
	    <para>Insérer un champ <filename>MAR_NUM</filename> dans la table <filename>PLANCHES</filename>, de même type que l'identifiant de la table <filename>MARQUES</filename></para></listitem>
	    <listitem>
	    <para>Créer un <emphasis>index</emphasis> sur ce champ</para></listitem>
	    <listitem>
	    <para>Faire la liaison avec la table <filename>MARQUES</filename> en utilisant le lien <filename>Gestion des relations</filename></para></listitem></orderedlist>
 </para>
<figure>
	    <title>Création de la clef étrangère</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="images/pma15.jpg" />
	      </imageobject>
	    </mediaobject>
	  </figure>
<para>Il ne reste plus qu'à mettre la base de données à jour .....</para>
      </sect3>
    </sect2>

    <sect2>
      <title>Exercices d'applications</title>
      <para>Reprenons notre base "formation" : 
<orderedlist>
	  <listitem>
	    <para>En modifiant la base, faites apparaître que les stagiaires sont inscrits dans un ou plusieurs modules.</para></listitem>
	  <listitem>
	    <para>En modifiant la base, faites apparaître que chaque module est enseigné par un formateur.</para></listitem>
<listitem>
	    <para>Insérez les données de votre inscription. </para></listitem>
</orderedlist></para>
    </sect2>

  </sect1>

  <!--  ================================= Chapitre 3 ============================= -->
  <sect1>
    <title>Requêtes SQL</title>  
    <para>Le langage <filename>SQL</filename> pour <foreignphrase>Structured Query Language</foreignphrase> est un langage standardisé d'accès au données des SGBDR. Comme tout langage, il a sa propre sémantique et sa propre syntaxe. Il permet à la fois de définir les données (<emphasis>LDD - Langage de définition de données</emphasis>), d'y accéder (<emphasis>LMD - Langage de manipulation de données</emphasis>) et d'en gérer les droits (<emphasis>LPD - Langage de protection des données</emphasis>). Dans le cadre du développement Web et grâce à l'assistance de PhpMyadmin, nous n'étudierons que la partie manipulation de données. </para>

    <sect2>
      <title>Sélection de données</title>
      <sect3>
    <title>Sélection simple et conditionnelle</title>

      <para>La commande <command>SELECT</command> est définie par la syntaxe
      suivante :</para>

      <para><programlisting>SELECT [DISTINCT ou ALL] * ou liste de colonnes
FROM nom de table ou de la vue
[WHERE prédicats]
[GROUP BY ordre des groupes]
[HAVING condition]
[ORDER BY ] liste de colonnes</programlisting></para>

      <itemizedlist>
        <listitem>
	    <para><command>SELECT</command> : permet de définir les colonnes résultats, le signe *
          retournant toutes les colonnes des enregistrements
          sélectionnés</para>
        </listitem>

        <listitem>
	    <para><command>FROM</command> : définit la table sur laquelle porte la requête</para>
        </listitem>

        <listitem>
	    <para><command>WHERE</command> : le filtre portant sur les données (conditions à 
          remplir pour que les lignes soient présentes dans le résultat</para>
        </listitem>

        <listitem>
	    <para><command>GROUP BY</command> : définition d'un sous-ensemble</para>
        </listitem>

        <listitem>
	    <para><command>HAVING</command> : filtre portant sur les résultats (conditions de
          regroupement des lignes)</para>
        </listitem>

        <listitem>
	    <para><command>ORDER BY</command> : tri des résultats</para>
        </listitem>
      </itemizedlist>

      <para>La commande permettant d'afficher l'ensemble des lignes d'une
      table est donc : <command>SELECT * FROM CLIENT</command></para>

      <para>Donc, afficher l'ensemble des lignes de notre table
      <command>PLANCHE</command> est donc :</para>

      <para><programlisting>SELECT * FROM planche </programlisting></para>

      <para><programlisting>PLA_NUM     PLA_MARQUE     PLA_MODELE     PLA_ANNEE     PLA_TAILLE     PLA_POIDS        
1  TIGA  SLALOM 260  1997  2  9   
2  EXOCET  WAVE 259  2000  2  7     
3  MISTRAL  BEAST  2003  2  5     
4  BIC  SAXO  2000  2  </programlisting></para>

      <para>Pour afficher des lignes avec certains champs, et renommer ces
      champs pour l'affichage des résultats, nous pouvons exécuter la requête
      suivante :</para>

      <para><programlisting>SELECT PLA_MARQUE AS MARQUE, PLA_MODELE AS MODELE FROM planche</programlisting></para>

      <para><programlisting>MARQUE     MODELE        
TIGA  SLALOM 260     
EXOCET  WAVE 259     
MISTRAL  BEAST     
BIC  SAXO</programlisting></para>

      <para>Nous pouvons égalemennt classer ces résultats par ordre
      alphabétique par exemple : un premier tri sur le nom de la marque, et un
      deuxième sur le modèle de la planche.</para>

      <para><programlisting>SELECT PLA_MARQUE AS MARQUE, PLA_MODELE AS MODELE FROM planche ORDER BY PLA_MARQUE ASC, PLA_MODELE ASC</programlisting></para>

      <para><programlisting>MARQUE     MODELE       
BIC  SAXO     
EXOCET  WAVE 259     
MISTRAL  BEAST     
TIGA  SLALOM 260</programlisting></para>

      <para>MySQL nous propose aussi de limiter l'affichage des résultats :
      nous pouvons par exemple afficher les deux premières lignes des
      résultats :</para>

      <para><programlisting>SELECT PLA_MARQUE AS MARQUE, PLA_MODELE AS MODELE FROM planche ORDER BY PLA_MARQUE ASC, PLA_MODELE ASC LIMITS 0,2</programlisting></para>

      <para>ou les lignes à  partir de la troisième jusque la denière :</para>

      <para><programlisting>SELECT PLA_MARQUE AS MARQUE, PLA_MODELE AS MODELE FROM planche ORDER BY PLA_MARQUE ASC, PLA_MODELE ASC LIMITS 2,-1
</programlisting></para>

      <para>Nous pouvons aussi supprimer les doublons dans les résultats en
      utilisant l'opérateur <emphasis role="bold">DISTINCT </emphasis></para>

      <para><programlisting>SELECT DISTINCT CLI_PRENOM AS PRENOM FROM client </programlisting></para>

      <para><programlisting>PRENOM
Ivan
Paul
Jean
Marc</programlisting> Il est également possible d'afficher des calculs dans
      les résultats. La calcul de la masse volumique des planches donnerait
      par exemple :</para>

      <para><programlisting>SELECT PLA_MARQUE, PLA_MODELE, PLA_POIDS / PLA_VOLUME AS MASSE_VOLUMIQUE FROM planche</programlisting></para>

      <para><programlisting>PLA_MARQUE     PLA_MODELE     MASSE_VOLUMIQUE      
TIGA  SLALOM 260  0.1   
EXOCET  WAVE 259  0.088607594936709   
MISTRAL  BEAST  0.045454545454545   
BIC  SAXO  0.08</programlisting></para>
</sect3>
<sect3>
      <title>Prédicats de sélection</title>

      <para>L'interêt d'une base de données ne se limite heureusement pas à  un
      simple listage des données. Il est généralement nécessaire de donner des
      conditions ou filtres. Seules seront sélectionnées les lignes
      satisfaisant aux conditions situées après la clause
      <command>WHERE</command>.</para>

      <para>La sélection des clients habitant à  <emphasis>ST-PAUL
      </emphasis>peut donc se faire avec la requête :</para>

      <para><programlisting>SELECT * FROM client WHERE CLI_VILLE = "ST-PAUL"</programlisting></para>

      <para><programlisting>CLI_ID     CLI_NOM     CLI_PRENOM     CLI_ADR     CLI_VILLE     CLI_TEL       
1  KURZWEG  Ivan  Rue des mouettes  ST-PAUL  0692012345     
3  PAYET  Jean  6 rue des hortensias  ST-PAUL  0262010203     
5  GRONDIN  paul  23 rue des rosiers  ST-PAUL  0263708090</programlisting></para>

      <para>Nous allons voir dans les paragraphes suivants l'ensemble des
      opérateurs permettant de réaliser les prédicats de sélection,
      c'est-à -dire les fonctions qui vous nous permettre d'appliquer des
      filtres sur les champs des enregistrements.</para>

      <sect4>
        <title>Opérateurs</title>

        <para>Nous avons à  notre disposition l'ensemble des opérateurs
        mathématiques et logiques courants :+ - * /</para>

        <table>
          <title>Opérateurs</title>

          <tgroup cols="2">
            <tbody>
              <row>
                <entry><emphasis role="bold">Opérateur</emphasis></entry>

                <entry><emphasis role="bold">Symbole</emphasis></entry>
              </row>

              <row>
                <entry>Addition</entry>

                <entry>+</entry>
              </row>

              <row>
                <entry>Soustraction</entry>

                <entry>-</entry>
              </row>

              <row>
                <entry>Multiplication</entry>

                <entry>*</entry>
              </row>

              <row>
                <entry>Division</entry>

                <entry>/</entry>
              </row>

              <row>
                <entry>ET logique</entry>

                <entry>AND</entry>
              </row>

              <row>
                <entry>OU logique</entry>

                <entry>OR</entry>
              </row>

              <row>
                <entry>NON logique</entry>

                <entry>NOT</entry>
              </row>

              <row>
                <entry>INFERIEUR</entry>

                <entry>&lt;</entry>
              </row>

              <row>
                <entry>SUPERIEUR</entry>

                <entry>&gt;</entry>
              </row>

              <row>
                <entry>EGALITE</entry>

                <entry>=</entry>
              </row>

              <row>
                <entry>Comparaison de chaînes</entry>

                <entry>LIKE</entry>
              </row>

              <row>
                <entry>Intervalle</entry>

                <entry>BETWEEN</entry>
              </row>
            </tbody>
          </tgroup>
        </table>

        <para>Nous pouvons ainsi sélectionner les planches qui datent d'avant
        2003 :</para>

        <para><programlisting>SELECT * FROM PLANCHE WHERE PLA_ANNEE &lt; 2003</programlisting></para>

        <para><programlisting>PLA_NUM     PLA_MARQUE     PLA_MODELE     PLA_ANNEE     PLA_TAILLE     PLA_POIDS     PLA_VOLUME       
1  TIGA  SLALOM 260  1997  2  9  90     
2  EXOCET  WAVE 259  2000  2  7  79     
4  BIC  SAXO  2000  2  8  100</programlisting></para>

        <para>En combinant les filtres, on peut récupérer les enregistrements
        des planches antérieures à  2003 et d'un volume inférieur à  100 litres
        :</para>

        <para><programlisting>SELECT * FROM PLANCHE WHERE PLA_ANNEE &lt; 2003 AND PLA_VOLUME &lt; 100</programlisting></para>

        <para><programlisting>PLA_NUM     PLA_MARQUE     PLA_MODELE     PLA_ANNEE     PLA_TAILLE     PLA_POIDS     PLA_VOLUME        
1  TIGA  SLALOM 260  1997  2  9  90     
2  EXOCET  WAVE 259  2000  2  7  79</programlisting></para>

        <para>La sélection des clients dont on a un numéro de GSM donnerait
        :</para>

        <para><programlisting>SELECT * FROM CLIENT WHERE CLI_TEL LIKE "06%"</programlisting></para>

        <para><programlisting>CLI_ID     CLI_NOM     CLI_PRENOM     CLI_ADR     CLI_VILLE     CLI_TEL      
1   KURZWEG  Ivan  Rue des mouettes  ST-PAUL  0692012345     
2  HOARAU  Paul  2 rue des Lilias  ST-PIERRE  0692101112</programlisting></para>

        <para>Ici, le caractères % permet de pérciser à  MySQL de sélectionner
        les enregistrements dont le numéro de téléphone est composé de laa
        manière suivante : la chaîne "06" suivie de n'importe quel
        caractère.</para>
      </sect4>

      <sect4>
        <title>Fonctions sur les chaînes</title>

        <para>En plus des différents opérateurs que nous avons vu au
        paragraphe précédent, nous pouvons également utiliser des fonctions
        sur les valeurs des champs. Nous n'en détaillerons que certaines, la
        liste complète de ces fonctions étant disponible dans la documentation
        de MySQL :</para>

        <itemizedlist>
          <listitem>
            <para><command>TRIM ([LEADING ou TRAILING ou BOTH] [caractère]
            FROM nom de colonne) </command>: permet de supprimer les espaces
            ou tout autre caractère spécifié avant (LEADING) ou après
            (TRAILING) le champ.</para>
          </listitem>

          <listitem>
            <para><command>UPPER(colonne) LOWER(colonne)</command> : passent
            respectivement en majuscule et minuscules les valeurs de la
            colonne</para>
          </listitem>

          <listitem>
            <para><command>SUBSTRING ( nom de colonne,M,N) </command>: extrait
            la sous-chaîne de caractère commençant à  la
            M<emphasis>ième</emphasis> lettre et de longueur N.</para>

            <para><programlisting>SELECT CLI_NOM, CLI_PRENOM, UPPER(CONCAT(SUBSTRING(CLI_NOM,1,1) , SUBSTRING(CLI_PRENOM,1 ,1))) AS INITIALES FROM CLIENT</programlisting></para>

            <para><programlisting>CLI_NOM     CLI_PRENOM     INITIALES      
KURZWEG  Ivan  KI   
HOARAU  Paul  HP   
PAYET  Jean  PJ   
PAYET  Marc  PM   
GRONDIN  paul  GP</programlisting></para>
          </listitem>
        </itemizedlist>
      </sect4>

      <sect4>
        <title>Fonctions sur les dates</title>

        <para>De la même manière, il est possible de travailler sur les dates
        :</para>

        <itemizedlist>
          <listitem>
            <para><command>EXTRACT ( YEAR ou MONTH ou DAY FROM nom de colonne
            ) </command>: permet d'extraire l'année, le numéro du mois ou le
            numéro du jour d'une date</para>
          </listitem>

          <listitem>
            <para><command>NOW()</command> : permet de récupérer la date et
            l'heure courante</para>
          </listitem>

          <listitem>
            <para><command>TO_DAYS(date) </command>: renvoie le nombre de
            jours depuis la date 0 jusque la date
            <emphasis>date</emphasis></para>
          </listitem>

          <listitem>
            <para><command>FROM_DAYS(date)</command> : renvoie le nombre de
            jours écoulées depuis la date <emphasis>date</emphasis></para>
          </listitem>
        </itemizedlist>

        <para>La sélection de toutes les locations effectuées pendant le mois
        d'octobre peut donc s'écrire :</para>

        <para><programlisting>SELECT * FROM loue WHERE MONTH(LOU_DATE) = 10</programlisting></para>

        <para><programlisting>LOU_ID     PLA_NUM     CLI_ID     LOU_DEBUT     LOU_FIN     LOU_DATE
1 1 2 14:10:00 15:12:00 2003-10-06
2 1 2 16:08:00 17:35:00 2003-10-15
3 2 2 13:36:00 14:35:00 2003-10-25
</programlisting></para>

        <para>Il existe de nombreuses autres fonctions de travail sur les
        dates, mais nous ne les passerons pas toutes en revue. Elles sont
        décrites précisément dans la documentation de MySQL.</para>
      </sect4>
</sect3>
<sect3>
  <title>Fonctions d'aggrégats</title>

      <para>Il existe des fonctions de statistiques permettant par exemple de
      calculer le nombre de lignes qu'une requête renvoie. L'utilisation de
      ces fonctions nécessite souvent la présence de la clause <command>GROUP
      BY</command>, permettant de créer des sous-ensembles de lignes : les
      enregistrements sont groupés selon la valeur des colonnes de la clause
      <command>GROUP BY</command>.</para>

      <para>Par exemple, nous souhaitons calculer le nombre de planche du
      magasin :</para>

      <para><programlisting>SELECT COUNT(PLA_MODELE) FROM PLANCHE

COUNT(PLA_MODELE)
4</programlisting></para>

      <para>Mais si notre requête vise désormais à  compter le nombre de
      planche par marque, nous devons grouper les lignes par marque, pour les
      compter :</para>

      <para><programlisting>SELECT COUNT(PLA_MODELE), PLA_MARQUE FROM planche GROUP BY PLA_MARQUE

COUNT(PLA_MODELE) PLA_MARQUE
1 BIC
1 EXOCET
1 MISTRAL
2 TIGA</programlisting></para>

      <para>La longueur moyenne des planches serait obtenue par la requête
      suivante : <programlisting>SELECT AVG(PLA_TAILLE), PLA_MARQUE FROM PLANCHE GROUP BY PLA_MARQUE</programlisting></para>

      <programlisting>AVG(PLA_TAILLE)     PLA_MARQUE      
2.7799999713898  BIC   
2.5899999141693  EXOCET   
2.5699999332428  MISTRAL   
2.6749999523163  TIGA</programlisting>

      <para>la durée moyenne de location pourrait être obtenue par :</para>

      <para><programlisting>SELECT SEC_TO_TIME( AVG(TIME_TO_SEC(LOU_FIN) - TIME_TO_SEC(LOU_DEBUT)) ) 
AS MOYENNE FROM loue</programlisting></para>

      <para><programlisting>MOYENNE      
01:09:20</programlisting></para>

      <para>Nous verrons dans le chapitre suivant qu'il est également possible
      de filtrer les résultats d'une requête en utilisant la clause
      <command>HAVING</command>.</para>
</sect3>
    </sect2>



    <sect2>
      <title>Insertion de données</title>
       <para>Nous souhaitons maintenant entrer des données dans les tables de
      la bases de données. </para>

      <para>La documentation de MySQL nous fournit la syntaxe de la commande
      SQL permettant d'insérer des enregistrements dans une table :</para>

      <para><command>INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO]
      nom_de_table [(nom_colonne,...)] VALUES ((expression |
      DEFAULT),...),(...),...</command></para>

      <para>Nous retiendrons de cette définition que pour insérer des données
      dans une table, nous devons avoir une instruction SQl du type :</para>

      <para><command>INSERT INTO NOM_TABLE (LISTE DES COLONNES) VALUES (LISTE
      DES VALEURS)</command></para>

      <para>Dans notre exemple, nous voulons insérer deux planches à  voiles
      :</para>

      <para><programlisting> INSERT INTO `planche` (`PLA_NUM`, `PLA_MARQUE`,
      `PLA_MODELE`, `PLA_ANNEE`, `PLA_TAILLE`, `PLA_POIDS`) VALUES ('1',
      'TIGA', 'SLALOM 260', '1997', '2,60', '9');</programlisting></para>

      <para><programlisting> INSERT INTO `planche` (`PLA_NUM`, `PLA_MARQUE`,
      `PLA_MODELE`, `PLA_ANNEE`, `PLA_TAILLE`, `PLA_POIDS`) VALUES ('2',
      'EXOCET', 'WAVE 259', '1999', '2,59', '7');</programlisting></para>

      <para>Un client se présente maintenant. Nous souhaitons l'enregistrer
      :</para>

      <para><programlisting> INSERT INTO `client` (`CLI_ID`, `CLI_NOM`, `CLI_PRENOM`,
      `CLI_ADR`, `CLI_TEL`) VALUES ('1', 'KURZWEG', 'Ivan', 'Rue des
      mouettes', '0692012345');</programlisting></para>

      <para>Il désire louer la planche de vagues Exocet. Nous devons donc
      enregistrer une ligne dans la table LOUE, en y mettant l'heure courante
      :</para>

      <para> <programlisting>INSERT INTO `loue` (`PLA_NUM`, `CLI_ID`, `LOU_DEBUT`,
      `LOU_FIN`) VALUES ('2', '1', NOW(), NULL);</programlisting></para>

      <para>Dans ce cas, nous avons insérer l'heure courante en utilisant la
      fonction SQL NOW(), qui nous renvoie l'heure au format TIME. Pour
      l'heure de retour, nous n'avons rien mis, en indiquant à  MySQL de
      remplir ce champ avec NULL.</para>

      
    </sect2>    



    <sect2>
      <title>Mise à jour de données</title>
       <para>Notre client a terminé sa session de navigation. Il nous ramène
      donc la planche à  voile, et nous devons maintenant mettre à  jour l'heure
      de retour du matériel. Pour ceci, nous allons utiliser l'instruction de
      modification de N-Uplet, donc la syntaxe est précisée par la
      documentation MySQL :</para>

      <para><cmdsynopsis>
UPDATE [LOW_PRIORITY] [IGNORE] nom_de_table SET
      nom_colonne1=expr1 [, nom_colonne2=expr2, ...] [WHERE where_definition]
      [ORDER BY ...] [LIMIT #]</cmdsynopsis></para>

      <para>Nous retiendrons pour le moment que la mise à  jour
      d'enregistrements se fait en utilisant une requête SQL de la
      forme</para>

      <para><command>UPDATE NOM_TABLE SET NOM_COL = VALEUR WHERE NOM_COL =
      VALEUR;</command></para>

      <para>Pour mettre à  jour l'occurence de la table LOUE représentant que
      le client numéro 1 a ramené la planche numéro 2 à  l'instant :</para>

      <para><programlisting>UPDATE LOUE SET LOU_FIN = NOW() WHERE PLA_NUM = 2 AND
      CLI_ID = 1;</programlisting></para>

      <para>Pour le moment, cette instruction marche correctement, puisque le
      client 1 n'a jamais loué la planche 2 auparavant. Dans le cas contraire,
      nous aurions surement eu quelques problèmes ...</para>
    </sect2>

 <sect2>
      <title>Suppression de N-Uplets</title>

      <para>La suppression de données en SQL se fait en exécutant
      l'instruction SQL DELETE :</para>

      <para><command>DELETE [LOW_PRIORITY] [QUICK] FROM nom_de_table [WHERE
      clause_where] [ORDER BY ...] [LIMIT lignes]</command></para>

      <para>Nous retriendrons de cette définition que pour supprimer un
      enregistrement d'une table, nous utiliserons une instruction de la forme
      :</para>

      <para><command>DELETE FROM NOM_TABLE WHERE CONDITION</command></para>

      <para>Dans notre exemple, supposons que nous souhaitons supprimer la
      planche numéro 2. Comme nous avons utilisé le format InnoDB pour la création des tables, et spécifié que les enregistrements doivent être supprimés en cascade, MySQL se chargera de supprimer automatiquement les lignes de la table LOCATION.</para>

      <para><command>DELETE FROM PLANCHE WHERE PLA_NUM = 2;</command></para>

    </sect2>

  </sect1>



  <!--  ================================= Chapitre 4 ============================= -->
  <sect1>
    <title>Notions de modélisation</title>
    <sect2>
      <title>Merise</title> 
      <para>
Utiliser des données dans un site Internet implique de les stocker dans une base de données. Le couple <command>Php/MySQL</command> a fait depuis longtemps ses preuves dans le domaine du développement Web. </para><para>Mais concevoir une base de données nécessite au préalable d'avoir <emphasis>identifié</emphasis>, puis <emphasis>organisé</emphasis> toutes les données nécessaires à l'application. Nous allons dans ce chapitre étudier une partie de la méthode Merise, liée à la modélisation des données. Elle consiste à concevoir un <emphasis>Modèle Conceptuel de Données</emphasis> (MCD), le transposer en <emphasis>Modèle Logique de Données Relationnelles</emphasis> (MLDR), puis à générer le <emphasis>Modèle Physique</emphasis> correspondant (MPD).</para>
       <sect3>
        <title>Une approche par niveaux - Le cycle d'abstraction</title>

        <para>Parce que la maintenance d'une application informatique met
        clairement en évidence plusieurs types de problèmes, depuis les
        modifications qu'entraîne un changement de matériel, jusqu'à  la
        refonte complète de l'application qu'exige la mise en place d'une
        réglementation totalement nouvelle, il a paru essentiel de dégager des
        niveaux correspondant à  ces préoccupations différentes. Pour Merise et
        la plupart des méthodes de conception, il est classique de mettre en
        évidence 3 niveaux de réflexion :</para>

        <sect4>
          <title>Le niveau conceptuel</title>

          <para>Il correspond à  la définition des finalités de l'entreprise en
          explicitant sa raison d'être. Ce niveau, décrit à  travers un
          ensemble de règle de gestion, traduit les objectifs et les
          contraintes qui pèsent sur l'entreprise. On y retrouve par exemple
          les règles de gestion du personnel, de tenue de la comptabilité, de
          livraison des produits finis, etc..</para>
        </sect4>

        <sect4>
          <title>Le niveau organisationnel</title>

          <para>Son rôle est de définir l'organisation qu'il est souhaitable
          de mettre en place dans l'entreprise. On parle de choix
          d'organisation. L'analyste précise les postes de travail, la
          chronologie des opérations, les choix d'automatisation, etc..</para>
        </sect4>

        <sect4>
          <title>Le niveau technique</title>

          <para>Enfin, sont intégrés les moyens techniques nécessaires au
          projet. Ils s'expriment en terme de matériels ou de logiciels, et
          sont les plus sujets à  changements (évolution technologique).</para>
        </sect4>

        <sect4>
          <title>Le cycle d'abstraction</title>

          <para>La conception du système d'information se fait par étapes,
          afin d'aboutir à  un système d'information fonctionnel reflétant une
          réalité physique. Il s'agit donc de valider une à  une chacune des
          étapes en prenant en compte les résultats de la phase précédente.
          D'autre part, les données étant séparées des traitements, il faut
          vérifier la concordance entre données et traitements afin de
          vérifier que toutes les données nécessaires aux traitements sont
          présentes et qu'il n'y a pas de données superflues. Cette succession
          d'étapes est appelée cycle d'abstraction pour la
          conception des systèmes d'information :</para>

          <orderedlist>
            <listitem>
              <para>Système d'information manuel</para>
            </listitem>

            <listitem>
              <para>Expression des besoins</para>
            </listitem>

            <listitem>
              <para>Modèle conceptuel</para>
            </listitem>

            <listitem>
              <para>Modèle logique</para>
            </listitem>

            <listitem>
              <para>Modèle physique</para>
            </listitem>

            <listitem>
              <para>Système d'information automatisé</para>
            </listitem>
          </orderedlist>

          <table>
            <title>Les différents modèles de Merise</title>

            <tgroup cols="4">
              <tbody>
                <row>
                  <entry><emphasis>Niveaux</emphasis></entry>

                  <entry><emphasis>Données</emphasis></entry>

                  <entry><emphasis>Traitements</emphasis></entry>

                  <entry><emphasis>Questions</emphasis></entry>
                </row>

                <row>
                  <entry><emphasis>Conceptuel</emphasis></entry>

                  <entry>Modèle Conceptuel des Données
                  (<abbrev>MCD</abbrev>)</entry>

                  <entry>Modèle conceptuel des Traitements
                  (<abbrev>MCT</abbrev>)</entry>

                  <entry>Quoi ?</entry>
                </row>

                <row>
                  <entry><emphasis>Organisationnel</emphasis></entry>

                  <entry>Modèle Logique des Données
                  (<abbrev>MLD</abbrev>)</entry>

                  <entry>Modèle Organisationnel des Traitements
                  (<abbrev>MCT</abbrev>)</entry>

                  <entry>Qui ? Où ? Comment ?</entry>
                </row>

                <row>
                  <entry><emphasis>Technique</emphasis></entry>

                  <entry>Modèle Physique des Données
                  (<abbrev>MPD</abbrev>)</entry>

                  <entry>Modèles Opérationnel des Traitements
                  (<abbrev>MOpD</abbrev>)</entry>

                  <entry>Comment ?</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
        </sect4>
      </sect3>

    </sect2>
    <sect2>
        <title>Dictionnaire des données</title>

        <para>Une des images les plus classique de l'informaticien est celle
        d'un technicien concevant des solutions géniales à  des problèmes qui
        ne lui sont pas posés, et rétif à  tout dialogue avec l'utilisateur.
        Même si les cas d'écoles qui sont présentés en formation ont des
        objectifs clairement posés sur un existant vide, dans la vie
        professionnelle, il en va généralement bien autrement. Lors des
        différentes interviews qui jalonnent l'étude préalable, l'analyste
        recense les données apparaissant dans les différents documents de
        l'entreprise. Au cours de la conception détaillée, il va tenter de les
        décomposer en <emphasis>données élémentaire</emphasis>s, et les
        épurer, c'est-à -dire n'en retenir que les pertinentes.</para>

        <para>Etablir un dictionnaire des données, c'est <emphasis>recenser
        l'ensemble des informations de l'application</emphasis>, et leur
        attribuer un type de données, c'est-à -dire indiquer sous quelle forme
        informatique elles seront enregistrées.</para>

        <sect3>
          <title>Etablir la liste des données élémentaires</title>

          <para>Une donnée élémentaire est une donnée qui ne peut être
          décomposée. Souvent les données brutes sont constituées de plusieurs
          parties, mais on ne doit décider de les décomposer qu'en fonction de
          l'usage qui en sera fait.</para>

          <example>
            <title>Exemple</title>

            <para>Une adresse postale d'un client est une donnée brute, qu'on
            peut décomposer en <emphasis>AdresseRue,</emphasis>
            <emphasis>CodePostal</emphasis> et <emphasis>Ville.</emphasis>
            Cela permet par exemple de sélectionner tous les clients d'une
            ville. Mais si on a aussi besoin de connaître tous les clients
            d'une rue, on sera alors obligé de décomposer
            <emphasis>AdresseRue</emphasis> en <emphasis>NuméroRue</emphasis>
            et <emphasis>NomRue.</emphasis></para>
          </example>
        </sect3>

        <sect3>
          <title>Epurer les données</title>

          <para>Lorsque deux noms recouvrent la même réalité, il s'agit d'une
          <emphasis>synonymie.</emphasis> Lorsqu'un même nom de données
          recouvre plusieurs réalités, il s'agit d'une
          <emphasis>polysémie.</emphasis> Il faut bien sûr supprimer ces deux
          défauts.</para>

          <example>
            <title>Exemple</title>

            <para><emphasis>CodeClient</emphasis> et
            <emphasis>referenceClient</emphasis> sont deux noms de données qui
            peuvent recouvrir la même réalité, c'est-à -dire le moyen
            d'identifier le client. Il ne faut donc retenir qu'un seul nom
            pour cette propriété.</para>
          </example>
        </sect3>

        <sect3>
          <title>Distinguer les données calculées des données non
          calculées</title>

          <para>Une donnée calculée est une donnée dont la valeur peut être
          obtenue en appliquant une règle de calcul aux valeurs d'autres
          données élémentaires. Ces données ne doivent pas entrer dans le
          modèle conceptuel des données.</para>
        </sect3>

        <sect3>
          <title>Dresser le dictionnaire des données</title>

          <para>Les données élémentaires, calculées ou non calculées, épurées
          et retenues pour leur pertinence, constituent le dictionnaire des
          données. Pour chacune d'elles, on précise le type et le domaine de
          définition. On indiquera également si elles sont calculées ou
          non.</para>
        </sect3>

        <sect3>
          <title>Exercice</title>

          <para>Tout au long de ce dossier, nous allons tenter de modéliser un
          système d'information concernant des accidents de la circulation. En
          voici les grands traits :</para>

          <para>Un club de chasse sous-marine désire informatiser les résultats de parties de chasse. Tous les pêcheurs du club sont connus sous un pseudo.
Les parties de chasse ne sont pas communes (chacun chasse individuellement). On considère 
qu'il ne peut y avoir qu'une seule chasse dans la même journée.
Les espèces sont cataloguées en fonction de leur niveau de tir (difficulté qu'ils présentent à
être chassés) et de leur poids moyen.</para>
<para>Lorsqu'on enregistre le résultat d'une chasse, seul le nombre de poissons par espèce est
comptabilisé (les poissons ne sont pas pesés : on raisonne toujours à partir du poids moyen).</para>
<para>Enfin, à chaque niveau de tir est associé un nombre de points (plus le niveau est élevé, plus le
nombre de points est important), qui permet d'attribuer un score à chaque partie de chasse.
L'objectif du club est de permettre d'établir les documents suivants :
<itemizedlist>
<listitem><para>l'inventaire des espèces de poissons et le niveau de tir qui leur est attribué</para></listitem>
<listitem><para> le récapitulatif du nombre de prises dans l'année pour l'ensemble des chasseurs du club</para></listitem>
<listitem><para>le bilan des parties de chasse pour un chasseur donné (NB : on désire voir apparaître le
    lieu où s'est effectuée chaque chasse).</para></listitem></itemizedlist>
</para>

          <example>
            <title>Exercice</title>

            <para>Etablir le dictionnaire des données pour ce SI. </para>
          </example>
        </sect3>
      </sect2>

      <sect2>
        <title>Propriété</title>

        <para><emphasis><emphasis role="bold">Définition</emphasis>
        :</emphasis> Appelée aussi information élémentaire, données
        élémentaire ou rubrique, la propriété désigné le plus petit élément
        d'information manipulable. Pour être correctement définie, une
        propriété doit toujours être décrite par un " nom de propriété ",
        prendre ses valeurs dans un domaine de valeurs et avoir un sens dans
        le système d'information étudié.</para>

      <note>
        <para>Une propriété est véritablement élémentaire
        si elle n'est pas décomposable en un ensemble de propriétés
        signifiantes plus petites. On dit alors qu'elle est atomique. Par
        exemple, une adresse postale peut être décomposé en : - numéro de rue
        - nom de rue - code postal - ville Mais cette décomposition fine n'est
        pas systématique, elle est uniquement guidée par la pertinence à 
        traduire une réalité de l'entreprise. Ainsi, il n'est pas nécessaire
        de découper une date en trois propriétés distinctes, jour, mois et
        année.</para></note>
      </sect2>

      <sect2>
        <title>Entités</title>

        <sect3>
          <title>Définition</title>

          <para><application>Une entité est un type d'élément (abstrait ou
          concret) du monde réel défini par : - une existence propre et une
          utilité pour l'organisation étudiée - des occurrences multiples
          (c'est-à -dire au moins deux) - des propriétés (au moins une), dont
          un identifiant. </application></para>
        </sect3>

        <sect3>
          <title>Formalisme</title>

          <para><application>L'entité est représentée par un
          rectangle.</application><figure>
              <title>Entité</title>

              <mediaobject>
                <imageobject>
                  <imagedata fileref="images/bdd_entite.jpg" />
                </imageobject>
              </mediaobject>
            </figure></para>
        </sect3>

        <sect3>
          <title>Exercice</title>

          <para>A partir du dictionnaire des données établi au paragraphe précédent, essayez de distinguer 4 entités représentant la gestion du cleb de chasse sous marine.</para>
        </sect3>
      </sect2>

      <sect2>
        <title>Identifiant</title>

        <sect3>
          <title>Définition</title>

          <para><application>Parmi toutes les propriétés d'une entité, une ou
          plusieurs d'entre elles doivent jouer un rôle particulier, celui de
          permettre de distinguer chaque occurrence de l'entité par rapport à 
          toutes les autres. Cette propriété ou groupe de propriétés est
          appelé identifiant. Il existe plusieurs types d'indentifiant :
          </application></para>

          <para><application>. <emphasis>Identifiant simple</emphasis> : il
          est composé d'une seule propriété (exemple précédent) .<emphasis>
          Identifiant composé</emphasis> : il est composé de deux propriétés
          ou plus. .<emphasis> Identifiant relatif</emphasis> : il est
          constitué pour partie d'une propriété appartenant à  une autre
          entité. . <emphasis>Identifiant hérité</emphasis> : il résulte d'un
          lien de dépendance avec une entité générique. </application></para>
        </sect3>

        <sect3>
          <title>Formalisme</title>

          <para><application>L'identifiant d'une entité est l'ensemble des
          propriétés soulignées.</application><figure>
              <title>Identifiant</title>

              <mediaobject>
                <imageobject>
                  <imagedata fileref="images/bdd_ident.jpg" />
                </imageobject>
              </mediaobject>
            </figure></para>
        </sect3>

        <sect3>
          <title>Exercice</title>

          <para><application>Indiquez les identifiants des entités définies
          dans l'exercice précédent. Justifiez vos choix</application></para>
        </sect3>
      </sect2>

      <sect2>
        <title>Associations</title>

        <para><emphasis role="bold">Définition</emphasis> : Une association
        est un type d'élément du monde réel défini par :<itemizedlist>
<listitem>
              <para> - une absence d'existence intrinsèque </para>
            </listitem>
<listitem>
              <para>- au moins une occurrence </para>
            </listitem>
<listitem>
              <para>- une dimension  (mesurée par le nombre d'entités rattachées) </para>
            </listitem>
<listitem>
              <para>- une utilité pour  l'organisation étudiée.</para>
            </listitem></itemizedlist> .</para>

        <para><emphasis role="bold">Formalisme</emphasis> : L'association est
        représentée par un ovale.<figure>
            <title>Association</title>

            <mediaobject>
              <imageobject>
                <imagedata fileref="images/bdd_assoc.jpg" />
              </imageobject>
            </mediaobject>
          </figure></para>

        <example>
          <title>Dimensions d'associations</title>

          <itemizedlist>
            <listitem>
              <para>Association entre deux entités (dimension 2) :<figure>
                  <title>Association binaire</title>

                  <mediaobject>
                    <imageobject>
                      <imagedata fileref="images/bdd_assoc_bin.jpg" />
                    </imageobject>
                  </mediaobject>
                </figure></para>
            </listitem>

            <listitem>
              <para>Association entre trois entités (dimension 3) :<figure>
                  <title>Association ternaire</title>

                  <mediaobject>
                    <imageobject>
                      <imagedata fileref="images/bdd_assoc_ter.jpg" />
                    </imageobject>
                  </mediaobject>
                </figure></para>
            </listitem>

            <listitem>
              <para>Association réflexive (dimension 1) :<figure>
                  <title>Association réflexive</title>

                  <mediaobject>
                    <imageobject>
                      <imagedata fileref="images/bdd_assoc_une.jpg" />
                    </imageobject>
                  </mediaobject>
                </figure></para>
            </listitem>
          </itemizedlist>
        </example>

        <para><emphasis>Exercice :</emphasis></para>

      <para>Représenter les associations reliant les entités de notre club de chasse sous marine.
</para>
      </sect2>

      <sect2>
        <title>Occurence</title>

        <para><emphasis role="bold">Définition</emphasis> : Une occurrence de
        propriété est une valeur que peut prendre une propriété.</para>

        <sect3>
          <title>Occurence d'une entité</title>

          <para>Une occurrence d'entité est un ensemble ayant une existence
          propre d'occurrences de ses propriétés.</para>

          <para><example>
              <title>Occurence d'une entité</title>

              <para>Soit l'entité suivante : <figure>
                  <title>Entité stagiaire</title>

                  <mediaobject>
                    <imageobject>
                      <imagedata fileref="images/bdd_entite_stag.jpg" />
                    </imageobject>
                  </mediaobject>
                </figure></para>

              <para>L'ensemble <citetitle>{PAYET, JEAN,
              23/10/1970}</citetitle> est une occurrence de l'objet
              <emphasis>STAGIAIRE</emphasis> car " <emphasis>PAYET</emphasis>
              " est une occurrence de la propriété <emphasis>NOM</emphasis>, "
              <emphasis>JEAN</emphasis> " une occurrence de
              <emphasis>PRENOM</emphasis> et " 2<emphasis>3/10/1970</emphasis>
              " une occurrence de
              <emphasis>DATE_DE_NAISSANCE</emphasis>.</para>
            </example></para>
        </sect3>

        <sect3>
          <title>Occurence d'une association</title>

          <para>Une occurrence de relation est constituée d'une et d'une seule
          occurrence de chacune des entités associées. L'occurrence de chacune
          des propriétés de l'association est en relation avec les occurrences
          des entités associées.</para>

          <example>
            <title></title>

            <para><figure>
                <title>Occurence d'une association</title>

                <mediaobject>
                  <imageobject>
                    <imagedata fileref="images/bdd_occur_assoc.jpg" />
                  </imageobject>
                </mediaobject>
              </figure>Soient les occurrences suivantes :</para>

            <para> {<emphasis>PAYET, JEAN, 23/10/1970</emphasis>} : une
            occurrence de l'entité " <emphasis>STAGIAIRE</emphasis> ".</para>

            <para> {<emphasis>BDD</emphasis>} et
            {<emphasis>JAVASCRIPT</emphasis>} : deux occurrences de l'entité "
            <emphasis>MODULE </emphasis>".</para>

            <para>12 peut être une occurrence de " <emphasis>NOTE</emphasis> "
            associée aux occurrences {<emphasis>PAYET, JEAN,
            23/10/1970</emphasis>} et {<emphasis>BDD</emphasis>} ; 13 une
            autre occurrence de " <emphasis>NOTE</emphasis> " associée aux
            occurrences {<emphasis>PAYET, JEAN, 23/10/1970</emphasis>} et
            {<emphasis>JAVASCRIPT</emphasis>}.</para>
          </example>
        </sect3>
      </sect2>

      <sect2>
        <title>Cardinalités</title>

        <para><emphasis role="bold">Définition</emphasis> : La cardinalité
        d'une entité par rapport à  une association s'exprime par deux nombres
        appelés cardinalité minimum et cardinalité maximum.</para>

        <para>La cardinalité minimale peut être égale à  0 ou à  1.</para>

        <para>Si la cardinalité est égale à  0, c'est qu'il existe au moins une
        occurrence de l'entité qui ne participe pas aux occurrences de
        l'association.</para>

        <para>Si la cardinalité est égale à  1, chaque occurrence de l'entité
        participe aux occurrences de l'association.</para>

        <para>La cardinalité maximale exprime le nombre maximum de fois oà¹ une
        occurrence de l'entité participe aux occurrences de l'association. On
        la note égale à  <emphasis role="bold">n</emphasis>, elle peut être
        égale à  1 ou à  tout autre nombre strictement positif (quand le nombre
        d'occurrences est quantifiable).<figure>
            <title>Cardinalité</title>

            <mediaobject>
              <imageobject>
                <imagedata fileref="images/bdd_card.jpg" />
              </imageobject>
            </mediaobject>
          </figure></para>

        <example>
          <title>Cardinalités</title>

          <para><figure>
              <title>Cardinalité</title>

              <mediaobject>
                <imageobject>
                  <imagedata fileref="images/bdd_card_ex.jpg" />
                </imageobject>
              </mediaobject>
            </figure></para>

          <itemizedlist>
            <listitem>
              <para>Un stagiaire peut ne pas avoir de note, c'est à  dire qu'il
              peut exister un stagiaire qui n'a pas passé l'évaluation
              (cardinalité minimum = 0).</para>
            </listitem>

            <listitem>
              <para>Un stagiaire peut être inscrit à  plusieurs module et avoir
              une note pour chacun des modules auxquels il est inscrit
              (cardinalité maximum = n)</para>
            </listitem>

            <listitem>
              <para>Il est possible que personne ne se présente à  l'évaluation
              pour un module (cardinalité minimum = 0)</para>
            </listitem>

            <listitem>
              <para>Plusieurs notes peuvent être attachées à  un même module
              (cardinalité maximum = n)</para>
            </listitem>
          </itemizedlist>
        </example>
      </sect2>
   <sect2>
        <title>Concepts du relationnel</title>

        <sect3>
          <title>Relations</title>

          <para>Comme pour le modèle entité - association, on définit des
          domaines dans lesquels des attributs prennent leur valeur. Une
          relation est un ensemble d'entités et sa description peut prendre la
          forme d'un tableau dans lequel chaque ligne représente une
          occurrence d'entité et chaque colonne un attribut.</para>


             

              <para>La relation <emphasis>COUREUR(nom, prénom,
              dateNaissance)</emphasis> peut se représenter par :
 
<table>
                  <title>Coureur</title>
                  <tgroup cols="3">
		  <thead>
		    <row>
		      <entry>Nom</entry>
		      <entry>Prénom</entry>
		      <entry>DateNaissance</entry>
		    </row>
		  </thead>
                  <tbody>
                      <row>
                        <entry>Payet</entry>
                        <entry>Jacques</entry>
                        <entry>01</entry>
                      </row>
                      <row>
                        <entry>Hoarau</entry>
                        <entry>Philippe</entry>
                        <entry>10</entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
</para>
<para>
          
              La relation ETAPES (NuméroEtape, VilleDépart,
              VilleArrivée, NbKm) peut se représenter par
<table>
                  <title>Etapes</title>

                  <tgroup cols="4">
                    <tbody>
                      <row>
                        <entry><emphasis role="bold">NuméroEtape</emphasis></entry>
                        <entry><emphasis role="bold">VilleDepart</emphasis></entry>
                        <entry><emphasis role="bold">VilleArrivee</emphasis></entry>
                        <entry><emphasis role="bold">NbKm</emphasis></entry>
                      </row>
                      <row>
                        <entry>1</entry>
                        <entry>St Denis</entry>
                        <entry>St Paul</entry>
                        <entry>50</entry>
                      </row>
                      <row>
                        <entry>2</entry>
                        <entry>St Paul</entry>
                        <entry>St Leu</entry>
                        <entry>30</entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
</para>
           
        </sect3>

        <sect3>
          <title>N-Uplets</title>

          <para>Un n-uplet est une occurrence d'une relation. Plus
          concrètement, il représente une ligne du tableau. On dit aussi
          <emphasis>t-uple</emphasis> au lieu de <emphasis>n-uplet</emphasis>.
          <emphasis role="bold">Exemple</emphasis> : (1,St Denis, StPaul, 50)
          est un <emphasis>n-uplet</emphasis> de la relation
          <emphasis>ETAPES</emphasis></para>
        </sect3>

        <sect3>
          <title>Cardinalité</title>

          <para>La cardinalité d'une relation est son nombre d'occurrence.
          Dans l'exemple précédent, la cardinalité de la relation
          <emphasis>COUREUR</emphasis> est de 2.</para>
        </sect3>

        <sect3>
          <title>Degré d'une relation</title>

          <para>Le degré d'une relation est son nombre d'attribut. . Dans
          l'exemple précédent, le degré de la relation
          <command>COUREUR</command> est de 3.</para>
        </sect3>

        <sect3>
          <title>Clef primaire</title>

          <para>Une clef primaire est constituée d'un ou plusieurs attributs
          de la relation. Elle permet d'identifier sans équivoque chaque
          n-uplet de la relation.</para>

          <para><emphasis>Dans la relation Coureur, NOM peut ne pas être
          suffisant pour distinguer les occurrences, en cas d'homonymie. On
          peut rajouter un attribut à  la relation, un numéro de coureur, qui
          devient clef primaire </emphasis></para>
        </sect3>

        <sect3>
          <title>Clef étrangère</title>

          <para>Selon les dépendances fonctionnelles observées, il peut être
          nécessaire de connaître la clef primaire d'une relation pour
          identifier un n-uplet d'une autre relation. Dans ce cas, la clef
          primaire de la première devient clef étrangère de la seconde.
          <emphasis role="bold"></emphasis></para>

          <para><emphasis><emphasis role="bold">Exemple</emphasis></emphasis>
          : soit la nouvelle relation qui permet de modéliser les temps des
          coureurs : <emphasis>TEMPS(NumCoureur, NumeroEtape,
          tempsrealisé)</emphasis>. Les clefs <emphasis>NumCoureur</emphasis>
          et <emphasis>NuméroEtape,</emphasis> clefs primaires des relations
          <emphasis>COUREUR</emphasis> et <emphasis>ETAPES,</emphasis>
          permettent d'identifier chaque n-uplet de la relation. En effet, un
          coureur ne participe qu'une seule fois à  une étape ! Ce sont donc
          les clefs étrangères de <emphasis>COUREUR.</emphasis></para>
        </sect3>

        <sect3>
          <title>Formalisme</title>

          <para>On représente chaque relation de la modélisation par :
          <command>NOMRELATION (clefPrimaire1, clePrimaire2, ..., attribut1,
          Attribut2, .. ,#clefEtrangère1,#clefEtrangère1)</command></para>

          <para><emphasis role="bold">Exemple</emphasis> : <emphasis>TEMPS
          (#NumCoureur,#NumeroEtape, tempsrealisé)</emphasis></para>

          <para><emphasis>COUREUR (NumCoureur, (nom, prénom,
          dateNaissance)</emphasis></para>

          <para><emphasis>ETAPES (NuméroEtape, VilleDépart, VilleArrivée,
          NbKm)</emphasis></para>
        </sect3>
      </sect2>


      <sect2>
        <title>Passage du MCD au MPD</title>

        <para>Le passage du MCD vers le modèle relationnel se base sur
        l'application de quatre règles simples, énoncées ci-dessous. Il est à 
        noter que cette transformation peut se faire en sens inverse, en
        appliquant les mêmes règles.</para>

        <sect3>
          <title>Règle 1</title>

          <para><emphasis role="bold">Toute entité  du MCD est traduite en une
          table dont la clef primaire et les attributs proviennent de
          l'entité</emphasis><figure>
              <title>Règle 1</title>

              <mediaobject>
                <imageobject>
                  <imagedata fileref="images/regle1.jpg" />
                </imageobject>
              </mediaobject>
            </figure></para>
        </sect3>

        <sect3>
          <title>Règle 2</title>

          <para><emphasis role="bold">Une association binaire qui a une cardinalité
          égale à  0,1 ou 1,1 pour une entité est traduite par une clef
          étrangère ajoutée à  la table qui traduit cette entité. Cette clef
          étrangère est la clef primaire de l'entité
          associée.</emphasis><figure>
              <title>Règle 2</title>

              <mediaobject>
                <imageobject>
                  <imagedata fileref="images/regle2.jpg" />
                </imageobject>
              </mediaobject>
            </figure></para>
        </sect3>

        <sect3>
          <title>Règle 3</title>

          <para><emphasis role="bold">Une association binaire qui n'a pas de
          cardinalité égale à  0,1 ou 1,1 est traduite en une table dont la
          clef primaire est constituée de l'ensemble des identifiants des
          entités qui y participent.</emphasis></para>

          <figure>
            <title>Règle 3</title>

            <mediaobject>
              <imageobject>
                <imagedata fileref="images/regle3.jpg" />
              </imageobject>
            </mediaobject>
          </figure>
        </sect3>

 <sect3>
          <title>Règle 4</title>

          <para><emphasis role="bold">Toute association ternaire et plus est traduite par une relation dont la clef primaire est constituée de l'ensemble des identifiants des entités qui y participent.</emphasis></para>

        </sect3>
      </sect2>

      <sect2>
        <title>Exercices</title>

        <sect3>
          <title>Base archéologique</title>

          <para>Vous gérez une base de données archéologique dans laquelle
          vous voulez mettre les informations suivantes. Un objet est trouvé
          par une équipe donnée, dans un site donné. L'équipe est reconnue par
          le nom de son directeur, et le site par son numéro, sa longueur, sa
          largeur. Le site appartient à  une zone de fouille qui peut en
          contenir plusieurs. La zone de fouille porte le nom de la ville la
          plus proche. L'objet est identifié par un numéro, une désignation
          (qui le décrit), une catégorie (par exemple, meuble, accessoire,
          élément d'architecture, manuscrit...), par un état de complétude
          (s'il est total ou s'il est partiel comme un pied de table, un
          tesson de bouteille ou un nez de gargouille, etc...) et par un état
          de conservation ( intact, bon, à  restaurer, mauvais état, très
          mauvais). Plusieurs équipes peuvent fouiller simultanément la même
          zone de fouille, mais pas le même site. En revanche les équipes
          tournent, d'un site à  l'autre, chaque jour. <emphasis>QUESTION
          </emphasis>: proposez un modèle entité-association représentant cet énoncé, en justifiant
          les cardinalités des couples entité-association, ainsi que les clés
          des entités. Proposez le modèle relationnel correspondant</para>
        </sect3>
      <sect3>
          <title>Gestion d'un bibliothèque universitaire</title>

          <para>La première étape de l'étude a dégagé les données suivantes à stocker :

<itemizedlist>
<listitem><para>Numéro d'ouvrage (NumeroOuvrage)</para></listitem>
<listitem><para>Titre de l'ouvrage (TitreOuvrage)</para></listitem>
<listitem><para>Numéro interne du livre attribué par la bibliothèque (NumeroInterne)</para></listitem>
<listitem><para>Numéro d'auteur (NumeroAuteur)</para></listitem>
<listitem><para>Nom de l'auteur (NomAuteur)</para></listitem>
<listitem><para>Numéro d'étudiant (NumeroEtudiant)</para></listitem>
<listitem><para>Nom de l'étudiant (NomEtudiant)</para></listitem>
<listitem><para>Numéro de la faculté (NumeroFaculte)</para></listitem>
<listitem><para>Nom de la faculté (NomFaculte)</para></listitem>
<listitem><para>Date du prêt (DatePret)</para></listitem>
<listitem><para>Date de retour (DateRetour)</para></listitem></itemizedlist>
</para><para>
Les contraintes :
<itemizedlist>
<listitem><para>Un ouvrage peut avoir plusieurs auteurs.</para></listitem>
<listitem><para>Un auteur peut écrire plusieurs ouvrages.</para></listitem>
<listitem><para>Un étudiant n'appartient qu'à une faculté et ne peut emprunter que trois livres à la fois.</para></listitem>
<listitem><para>Un ouvrage figure en plusieurs exemplaires dans la bibliothèque.</para></listitem>
<listitem><para>Le délai d'emprunt d'un livre est de trois semaines. Au-delà de cette période, l'étudiant doit payer une pénalité.</para></listitem>
</itemizedlist>
</para></sect3>
 <sect3>
          <title>GESTION DES CONCOURS</title>

          <para>        Une école désire gérer la participation de ses élèves à divers concours d'entrée dans la fonction pulique. Chaque élève est encadré par un tuteur de l'école.
Dans chaque concours, l'élève doit réaliser un projet qu'il choisit lui-même. Le jury
accorde toujours un nombre de points qui permet d'établir le classement (si 2 élèves ont le
même nombre de points, ils sont ex-æquos).</para><para>
On désire connaître les concours auxquels ont participé les élèves, le projet réalisé, la place
et le nombre de points qu'ils ont obtenus (NB : pour la place, on ne gère que les élèves de
l'école).</para>
<para>Les informations collectées sont :
<itemizedlist>   
<listitem><para>  nom de l'élève </para></listitem>
<listitem><para>  prénom de l'élève</para></listitem>
<listitem><para>  nom du tuteur</para></listitem>
<listitem><para>  prénom du tuteur</para></listitem>
<listitem><para>  nom du concours</para></listitem>
<listitem><para>  lieu du concours</para></listitem>
<listitem><para>  dotation globale du concours</para></listitem>
<listitem><para>  date du concours</para></listitem>
<listitem><para>  nombre de points obtenus</para></listitem>
<listitem><para>  place obtenue</para></listitem>
<listitem><para>  nom projet réalisé</para></listitem></itemizedlist>
</para>
<para>Donnez le MCD correspondant, puis  le modèle relationnel.</para>
</sect3>
        <sect3>
          <title>Gestion des HLMs</title>

          <para>La société OPHCO a la charge de la gestion des immeubles HLM des villes de plus de 5.000 habitants du département. Actuellement, on compte une douzaine de villes de ce type. La gestion des immeubles recouvre notamment l'affectation des appartements en fonction des demandes, la facturation des loyers, les travaux d'entretien, le suivi des règlements, etc... Dans l'optique d'une informatisation prochaine du système de gestion, on vous demande de poursuivre une étude des données, qui a abouti pour l'instant à : 
<itemizedlist>
	    <listitem>
	    <para>une liste des données à utiliser dans le système d'information ,</para></listitem> 
	    <listitem>
	    <para>la liste des règles de gestion à respecter.</para></listitem></itemizedlist></para>
<para>Voici la liste des données : 
<itemizedlist>
<listitem><para>Revenu Locataire</para></listitem>
<listitem><para>Loyer Mensuel</para></listitem>
<listitem><para>Type Appart 	</para></listitem>
<listitem><para>Code Gardien</para></listitem>
<listitem><para>N° Cité</para></listitem>
<listitem><para>Nom Cité</para></listitem>
<listitem><para>Code Appartement</para></listitem>
<listitem><para>N° Contrat</para></listitem>
<listitem><para>Nom Ville</para></listitem>
<listitem><para>Nom Locataire</para></listitem>
<listitem><para>N° Etage</para></listitem>
<listitem><para>Nom Gardien</para></listitem>
 <listitem><para>Garage (O/N) 	</para></listitem>
 <listitem><para>N° Immeuble</para></listitem>
 <listitem><para>Date Signature Bail</para></listitem>
 <listitem><para>Prénom Gardien</para></listitem>
 <listitem><para>Prénom Locataire</para></listitem>
 <listitem><para>Superficie Appart.</para></listitem>
	     <listitem><para>Durée Bail</para></listitem>
	    <listitem>
	    <para>N° Porte</para></listitem></itemizedlist>
</para>
<para>Voici les règles de gestion : 
<orderedlist>
<listitem><para>RG 1 - Pour une ville (de plus de 5.000 habitants) du département, il existe au moins une cité HLM.</para></listitem>
<listitem><para>RG 2 - Chaque cité HLM est identifiée par un numéro.</para></listitem>
<listitem><para>RG 3 - Pour un numéro de cité, il existe un nom de ville et un seul.</para></listitem>
<listitem><para>RG 4 - Un même nom de cité peut être utilisé pour plusieurs cités différentes, mais dans des villes différentes.</para></listitem>
<listitem><para>RG 5 - Chaque cité est surveillée par un gardien et un seul, mais un gardien peut surveiller plusieurs cités d'une même ville.</para></listitem>
<listitem><para>RG 6 - Chaque cité peut comporter jusqu'à 6 types d'appartements.</para></listitem>
<listitem><para>RG 7 - Une cité comporte plusieurs immeubles, numérotés de 1 à N. Chaque immeuble contient au moins 2 types d'appartements.</para></listitem>
<listitem><para>RG 8 - Chaque appartement est identifié par un code.</para></listitem>
<listitem><para>RG 9 - Un appartement peut disposer d'un garage, mais ce n'est pas toujours le cas.</para></listitem>
<listitem><para>RG 10 - Un appartement peut être occupé par un locataire, qui signe un contrat de location.</para></listitem>
<listitem><para>RG 11 - Chaque contrat est identifié par un numéro, et permet de fixer le montant du loyer valable pour la </para></listitem>durée du bail.
</orderedlist>
</para>
<para>Vous devez modéliser le système d'information selon le formalisme MCD, puis en donner le modèle relationnel.</para>
        </sect3>
  <sect3>
      <title>Vidéothèque</title>

      <para>On souhaite réaliser la gestion d'une vidéothèque personnelle,
      sachant que le prêt à  ses amis devient vite un casse tête et une source
      de perte non négligeable ;-). Pour gérer ce problème, on dispose des
      informations suivantes : </para>

      <itemizedlist>
        <listitem>
          <para>Un film possède les caractéristiques suivantes : Un code, un
          titre, une année de sortie, une durée et un résumé.</para>
        </listitem>

        <listitem>
          <para>Dans les films jouent des acteurs, ayant bien sûr un nom et un
          prénom.</para>
        </listitem>

        <listitem>
          <para>Chaque film est d'un genre particulier</para>
        </listitem>

        <listitem>
          <para>On dispose dans notre vidéothèque de plusieurs supports : VHS,
          DIVX, DVD, mà¹ais on ne prete que les VHS</para>
        </listitem>

        <listitem>
          <para>On prend soin d'enregistrer les personnes empruntant les
          films, en retenant leur adresse et leur téléphone. </para>
        </listitem>
      </itemizedlist>
    </sect3>

 <sect3>
      <title>Entreprise de plomberie</title>

      <para>
Il s'agit d'une petite entreprise artisanale de plomberie, chauffage et d'électricité qui travaille pour des particuliers qui construisent ou rénovent leur maison.</para>

<para>
 La société emploie :
 <itemizedlist>   <listitem><para> M. Durand gérant de l'entreprise</para></listitem>
   <listitem><para> Mme Durand secrétariat,</para></listitem>
   <listitem><para> M. Durand fils chef de chantier</para></listitem>
   <listitem><para> M. Duval chef magasinier</para></listitem>
   <listitem><para> des ouvriers</para></listitem> </itemizedlist> 
</para><para>
C'est M. Durand qui s'occupe des contacts avec la clientèle et de la négociation des devis : après visite du client, il fait une offre (prestation, prix). Une discussion s'engage avec le client qui peut amener à modifier le devis initial. Par contre, le devis signé ne peut plus être modifié. Un devis se voit attribuer un numéro. Au final le devis devra faire apparaître les données suivantes :
 <itemizedlist>
        <listitem><para> numéro du devis ( calcué de façon incrémentale )</para></listitem>
   <listitem><para> identification complète du client ( nom, prénom,adresse,téléphone,fax,e-mail)</para></listitem>
   <listitem><para> lieu des travaux ( adresse complète )</para></listitem>
   <listitem><para> la date de signature</para></listitem>
   <listitem><para> la date du début des travaux</para></listitem>
   <listitem><para> descriptif des prestations et coûts des prestations</para></listitem>
   <listitem><para> montant global du devis</para></listitem> </itemizedlist>
</para><para>
M. Durand n'accepte un chantier que si le client a signé au préalable un devis. Lorsque l'affaire est conclue, celle-ci est enregistrée et mise dans le planning des chantiers. Il faut alors rechercher les articles et les fournitures à commander aux fournisseurs : tout chantier doit démarrer à la date promise au client.
Un chantier est caractérisé par :
 <itemizedlist>
        <listitem> <para>numéro</para></listitem>
   <listitem><para> identification complète du client</para></listitem>
   <listitem><para> lieu des travaux</para></listitem>
   <listitem><para> date début de chantier</para></listitem>
   <listitem><para> durée chantier</para></listitem>
   <listitem><para> liste des ouvriers affectés</para></listitem>
   <listitem><para> liste des fournitures nécessaires  </para></listitem> </itemizedlist>
</para><para>
Les fournitures sont commandées directement aux représentants de différents grossistes lors de leur passage dans l'entreprise.
C'est Mme Durand qui enregistre les devis signés en fin de semaine. Elle prépare les commandes aux fournisseurs (qui doivent être visées par M. Durand) et donne au magasinier la liste des articles à sortir au début du chantier. Elle est aussi en charge de la comptabilité.</para><para>
Le chef magasinier est en charge des planning de travail, il choisit les produits à commander en fonction des devis et des catalogues fournisseurs, et organise les travaux sur les chantiers.
M. Duval, chef magasinier, trie les articles lors de la livraison. Les articles courants (tuyaux de cuivre, colliers...) sont rangés dans des rayons par famille de produits et les articles spécifiques à un chantier sont rangés dans un casier spécial au nom du client.
Un article est référencé par :
 <itemizedlist>
        <listitem>
          <para>Code famille</para></listitem>
   <listitem><para> Code produit</para></listitem>
   <listitem><para> Libellé produit</para></listitem>
   <listitem><para> Quantité en stock</para></listitem>
   <listitem><para> Prix produit HT</para></listitem> </itemizedlist>
</para><para>
On prépare un chantier huit jours avant son ouverture pour s'assurer que les articles nécessaires sont disponibles. Si ce n'est pas le cas, la secrétaire effectue une relance urgente auprès des fournisseurs. C'est lors de la préparation du chantier que sont affectés les ouvriers par le chef de chantier. 

 </para>


    </sect3>

    <sect3>
      <title>Travail à  faire</title>
      <para>On vous fournit le dictionnaire des données suivant :</para>
 <itemizedlist>
   <listitem><para>dDevis: Identifiant devis </para></listitem>
   <listitem><para>DateS :	Date signature devis </para></listitem>
   <listitem><para>IdCli :	Identifiant client 	</para></listitem>
   <listitem><para>Nom :	Nom du client 	</para></listitem>
   <listitem><para>Adresse Fac :	Adresse de facturation client </para></listitem>
   <listitem><para>Adresse chantier :	Adresse du chantier client </para></listitem>
   <listitem><para>Tel: 	téléphone client 	</para></listitem>
   <listitem><para>Idchantier :	Identifiant chantier 	</para></listitem>
   <listitem><para>Date début chantier 	</para></listitem>
   <listitem><para>Durée chantier 	</para></listitem>
   <listitem><para>IdPrestation :	Identifiant Tache effectuée sur le chantier </para></listitem>
   <listitem><para>Libelle prestation 	</para></listitem>
   <listitem><para>Coût prestation :	coût d'une tache 	</para></listitem>
   <listitem><para>Montant global devis :	Cout chantier à facturer ht 	(somme (coût chaque prestation) + somme (prix*qté) chaque prod)</para></listitem>
   <listitem><para>Montant global devis TTC :	Cout chantier à facturer ttc 	(Mont glob. devis * TVA)</para></listitem>
   <listitem><para>IdOuvriers :	Ouvrier travaillant ds l'entreprise 	</para></listitem>
   <listitem><para>Nom ouvrier :	Nom Ouvrier travaillant ds l'entreprise 	</para></listitem>
   <listitem><para>Ouvriers affectés :	Ouvrier de l'entreprise affecté à un chantier 	</para></listitem>
   <listitem><para>Code produit :	Id produit 	</para></listitem>
   <listitem><para>Libelle Produit :	Libelle du produit 	</para></listitem>
   <listitem><para>Prix Produit ht :	prix du produit à facturer 	</para></listitem>
   <listitem><para>Qté en stock 	</para></listitem>
   <listitem><para>Qté prod :	Qté prod affectée à chantier 	</para></listitem>
   <listitem><para>Code famille :	Identifiant famille produit 	</para></listitem>
   <listitem><para>Libelle famille :	Libelle famille produit 	</para></listitem>
 </itemizedlist>
<para>Vous devez faire : 
      <orderedlist>
        <listitem>
          <para>Le modèle conceptuel des données</para>
        </listitem>
        <listitem>
          <para>Le modèle logique des données (modèle relationnel).</para>
        </listitem>
      </orderedlist>
</para>
    </sect3>


      </sect2>

  </sect1>




  <!-- =================================================================== -->
  <bibliography> 
    <title>Références</title> 

    <bibliodiv> 
      <biblioentry> 
 	<abbrev>1</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Welling</firstname>
	      <surname>Luke</surname>
	    </personname>	 
	  </author> <author>
	    <personname>
	      <firstname>Thomson</firstname>
	      <surname>Laura</surname>
	    </personname>	  
	  </author>
	</authorgroup>
 	<title>PHP and MySQL - Web Development</title> 
 	<edition> 
SAMS Edition
         </edition> 
      </biblioentry> 

      <biblioentry> 
 	<abbrev>2</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Ratschiller</firstname>
	      <surname>Tobias</surname>
	    </personname>	 
	  </author> <author>
	    <personname>
	      <firstname>Gerken</firstname>
	      <surname>Till</surname>
	    </personname>	  
	  </author>
	</authorgroup>
 	<title>Web Application Development with Php 4.0</title> 
 	<edition> 
New Riders
         </edition> 
      </biblioentry> 

      <biblioentry> 
 	<abbrev>3</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Valade</firstname>
	      <surname>Janet</surname>
	    </personname>	 
	    
	  </author>
	</authorgroup>
 	<title>PHP and MySQL for Dummies</title> 
 	<edition> 
Wiley Publishing, Inc
         </edition> 
      </biblioentry> 
      <biblioentry> 
 	<abbrev>4</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Lane</firstname>
	      <surname>David</surname>
	    </personname>	 
	    
	  </author>
	</authorgroup>
 	<title>Web database applications</title> 
 	<edition> 
O'Reilly
         </edition> 
      </biblioentry>     

      <biblioentry> 
 	<abbrev>5</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Vailly</firstname>
	      <surname>Alain</surname>
	    </personname>	 
	    
	  </author>
	</authorgroup>
 	<title>Genie Logiciel</title> 
 	<edition> 
Ellipses - Technosup 
         </edition> 
      </biblioentry>         <biblioentry> 
 	<abbrev>6</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Tardieu</firstname>
	      <surname>Hubert</surname>
	    </personname>	 
	    
	  </author>
	  <author>	   
	    <personname>
	      <firstname>Rochfeld</firstname>
	      <surname>Arnold</surname>
	    </personname>	 
	    
	  </author>	  <author>	   
	    <personname>
	      <firstname>Coletti</firstname>
	      <surname>René</surname>
	    </personname>	 
	    
	  </author>
	</authorgroup>
 	<title>La méthode Merise</title> 
 	<edition> 
Editions d'organisation
         </edition>
      </biblioentry>         <biblioentry> 
 	<abbrev>7</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	      <firstname>Collongues</firstname>
	      <surname>Alain</surname>
	    </personname>	 
	    
	  </author>
	</authorgroup>
 	<title>Merise</title> 
 	<edition> 
Dunod Informatique
         </edition> 
      </biblioentry>   
    </bibliodiv> 
  </bibliography> 
</article>

