Définition des données
Dans notre premier exemple, nous allons travailler sur deux tables : une qui contiendra les compagnies aériennes, et l’autre qui décrira les pilotes rattachés à leur compagnie. Les commandes suivantes créent les tables Compagnie et Pilote avec les syntaxes SQL d’Oracle et Microsoft. La clause PRIMARY KEY permet de déclarer une clé primaire, la clause FOREIGN KEY, une clé étrangère. Avec la clause CONSTRAINT, vous pouvez programmer tout autre type de contrainte en la nommant (valable également pour les clés primaires ou étrangères). Nous avons limité à l’aide d’une contrainte le domaine de valeurs de l’âge des pilotes (ici la contrainte se nomme ck_age_ pilote et assurera que l’âge de chaque pilote sera toujours compris entre 20 et 60 ans). Les commandes INSERT, UPDATE, et DELETE permettent respectivement d’insérer, de modifier et de supprimer des enregistrements d’une table. Concernant les deux dernières fonctionna- lités, on peut filtrer ces instructions selon des critères définis avec la directive WHERE. Le langage SQL permet d’extraire des informations de la base de données en fonction de critères. Pour ce faire, il faut recourir à une instruction de type SELECT appelée « requête ». À titre d’exemple, nous cherchons les pilotes âgés de 20 à 35 ans, qui n’appartiennent pas à la compagnie de code ‘AF’. La requête qu’il convient d’utiliser est la suivante (le signe « * » sélectionne toutes les colonnes de la table).
Interface SQL*Plus d’Oracle
Il est possible de rédiger des questions plus complexes mettant en jeu plusieurs tables, et faisant la plupart du temps intervenir des jointures. Supposons que le contenu des tables soit à présent celui de la figure 3-6, et que vous souhaitiez connaître le nom des pilotes âgés de 35 à 37 ans, qui appartiennent à une compagnie embauchant plus de deux pilotes, et dont le budget dépasse la moyenne des budgets des compagnies. On se rend compte que le concepteur de cette base n’a pas forcément pris en compte la nécessité d’effectuer cette requête lors de la conception. Cela illustre une des fonctionnalités des bases de données, à savoir le fait de ne pas connaître exhaustivement les requêtes à soumettre, et qu’on peut déduire des informations en rapprochant des faits élémentaires entre eux. Les SGBD prennent en compte l’intégrité des données définies via la déclaration de contraintes ou la programmation de fonctions ou de procédures cataloguées, de paquetages (packages) ou de déclencheurs (triggers). Le principe est simple : assurer la cohérence de la base après chaque modification (par INSERT, UPDATE ou DELETE).
Dans l’exemple, trois contraintes ont été déclarées sur la table Pilote, elles permettent de programmer les domaines d’attributs du modèle relationnel. La première (pk_pilote) indique que le numéro du brevet est unique, la deuxième (fk_pilote_compa_compagnie) indique que la compagnie du pilote doit être référencée dans la table compagnie, la troisième (ck_age_pilote) définit un intervalle d’âge possible pour tout pilote. Chaque contrainte est nommée. Ce principe facilite la désactivation temporaire et la réactivation des contraintes avec la commande ALTER TABLE. Dans notre exemple, il était incorrect d’insérer un pilote d’une compagnie non référencée dans la base. Il est tout aussi incorrect de vouloir supprimer une compagnie à laquelle des pilotes sont rattachés. La suppression d’une compagnie est envisageable en effectuant en contrepartie des actions compensatoires, comme modifier tous les pilotes qui dépendent de cette compagnie (en affectant la valeur nulle à la colonne compa) ou en supprimer tous les pilotes concernés ! Ces actions peuvent être définies avec la directive CASCADE et sont déclarées avec la table concernée comme une contrainte. Nous étudions la traduction des associations un-à-un, un-à-plusieurs, plusieurs-à-plusieurs et réflexives. Nous illustrons nos exemples avec les formalismes Merise et UML de manière à ce que le lecteur puisse mieux appréhender les niveaux conceptuel, logique et physique.