Fondements de
Septembre 2005
(Révisé Février 2008)
Michel LEONARD
Professeur Ordinaire
TABLE DES MATIERES
1. INTRODUCTION AUX SYSTEMES DE GESTION DE BASES DE
DONNEES
1.1 Introduction aux bases de données
1.1.1 Utilité des bases de données
1.1.3 Principe fondamental des systèmes de gestion de
bases de données
1.2 Introduction aux systèmes de gestion de bases de
données
1.2.1 Description et utilisation des informations
(définition, interrogation, mise-à-jour)
1.2.2 Gestion et contrôle d’intégrité
1.2.3 Mise en œuvre de la confidentialité
1.2.4 Gestion des accès concurrents
1.2.5 Assurance d’une certaine sécurité de fonctionnement
2. CLASSE - RELATION - ENTITE - OBJET
2.2.4 Différents types d’attributs
2.2.6 N-uplets, objets et instances
2.2.7 Identifiants ou clés d’une classe
2.3 Prise en compte informatique d’une classe
2.3.2 Décomposition d’une classe
2.4 Forme normale de classe, classe normale
2.4.1 Monde relationnel et forme normale de classe
2.4.2 Monde objet et classe normale
2.4.3 Opérations relatives aux classes
2.4.4 Opérations de déclaration d’une classe
2.5.3 Langage de manipulation d’objets d’une
relation/classe
3.1.1 Association dans le monde informatique :
chemin d’accès
3.1.2 Association dans le monde vivant
3.1.3 Association dans le monde informationnel
3.1.4 Les associations du point de vue des systèmes
d’information
3.1.6 Conclusions et plan du chapitre
3.2 Le monde informatique des bases de données et les
associations
3.2.2 Chemin d’accès monovalué
3.2.4 La prise en compte des chemins d’accès inverses
3.2.5 Implémentation d’une paire de chemins d’accès
3.2.6 Mécanismes de base relatifs aux associations
3.2.7 Opérations sur plusieurs classes
3.2.8 Machine abstraite de base de données
3.3 Le monde informationnel et les associations
3.3.1 Le recouvrement entre le monde artificiel
informatique et le monde informationnel
3.3.3 Différentes formes de composition de classes
3.3.4 Ambiguïtés sur les attributs
3.3.5 Ambiguïtés sur les relations
3.4 Le monde vivant et les associations
3.4.1 Monde vivant et schéma de classes
3.4.2 Correspondance entre les faits et les objets
3.4.3 Correspondances entre activités et opérations
d’interrogation
3.5.1 Correspondance entre les faits et les objets
3.5.2 Correspondances entre activités et opérations
d’interrogation
4.2 Définition d’une règle d’intégrité
4.3 Types particuliers de règles d’intégrité
4.4 Spécification de la validation des règles d’intégrité
4.4.1 Enjeux informatiques de la validation des règles
d’intégrité
4.4.2 Tableau de portée des règles
4.4.3 Tableau des risques d’une primitive
4.4.4 Constat de l’espace informationnel
4.5 Adaptation d’un schéma de classes à la validation des
règles
4.5.1 Nouveau schéma de classes
4.5.2 Nouvelles règles d’intégrité
4.5.3 Transformation des règles d’intégrité MaxPers et
+Jeune
4.5.4 Nouveau tableau de portée
4.5.5 Nouveau tableau récapitulatif des risques pour
la primitive créerAffectation
4.5.6 Nouveau constat de l’espace informationnel de la
primitive
5. Transactions, Traitements et Information
5.1.3 Transaction ou processus
5.2 Le monde de l’informatique
5.2.2 Cycle de
vie primitif de tout objet
5.2.3 Etat,
opération, traitement
5.3 Conclusions: vers le monde de l’information et de la
communication
I. TRAVAUX PRATIQUES : GESTCDE
I.1 Explication de modélisation
I.3 Opération sur plusieurs classes
I.4 Dépendances référentielles et existentielles
II. TRAVAUX PRATIQUES : PARCVEH
II.3 Opération sur plusieurs classes
III. CORRECTION DES TRAVAUX
PRATIQUES: GESTCDE
III.1 Explication de modélisation
III.2 Opération sur une classe
III.3 Opération sur plusieurs classes
III.4 Dépendances référentielles et existentielles
IV. CORRECTION DES TRAVAUX PRATIQUES:
PARCVEH
IV.3 Opération sur plusieurs classes
Au tout début il y a des personnes qui s’unissent pour entreprendre des
activités en commun. Il faut souvent de puissants liens entre ces personnes
pour que les épreuves rencontrées soient surmontées. L’origine de ces liens est
multiple, depuis la coercition jusqu’à l’amitié, l’esprit de corps, les liens
familiaux ou d’amour, depuis le désir de « s’en sortir » jusqu’à
celui de la découverte, en passant par celui de s’enrichir sans oublier celui
de survivre. Cette Histoire est très vieille, sans doute aussi vieille que
l’Humanité.
Ensuite, mais vraiment tout récemment, disons depuis 1950, c’est-à-dire dès
le moment où les personnes ont cessé d’être obnubilées par la guerre,
l’inventivité humaine s’est emparée à haute dose des capacités électroniques
pour traiter l’information et surtout entreprendre des calculs vertigineux.
Déjà pendant la guerre, ces capacités électroniques et les raisonnements qu’ils
demandaient avaient commencé par rendre de très grands services : le
décodage des messages secrets conduit par le grand savant anglais Turing en est
un illustre exemple. Pour qu’elle émerge, il a fallu des personnes qui créent
des liens très forts entre elles pour surmonter les affres des processus de
création. Certaines ont travaillé dans des hangars, d’autres dans des
sous-sols, toutes les nuits et les week-ends tellement elles étaient
passionnées par ce mouvement de création utile pour le développement de
L’informatique est une discipline toute jeune. A priori, ce n’est qu’une
simple technique. Pourtant elle révolutionne en peu de temps (une dizaine
d’années) des champs entiers de connaissances scientifiques. En fait ses
résultats directs visibles ne concernent pas la production de nouvelles
connaissances. Ils concernent la constitution de laboratoires qui ont permis
des explorations tout simplement impossibles sans elle. Et ces explorations ont
conduit à de nouvelles connaissances, de nouveaux savoir-faire notamment
d’ingénierie dans tous les domaines, à la conception et fabrication de nouveaux
produits.
Souvent les informaticiens étaient considérés comme de simples techniciens,
de plus totalement incompréhensibles et sans envergure, leur travail se
limitant à faire tourner des ordinateurs, à écrire des programmes, à passer
leur temps – et souvent leurs nuits – à trouver les petites bêtes (les bugs)
qui faisaient planter leurs programmes. Les grands savants d’autres disciplines
scientifiques, comme la physique, les mathématiques, regardaient l’informatique
avec beaucoup de condescendance en expliquant : certes, l’informatique est
utile, même indispensable, mais ce n’est qu’une technique, ne pouvant jamais
générer directement aucune connaissance universelle comme les mathématiques et
la physique.
Mais, si l’on enlève les masques du carnaval de l’apparence, si l’on se
donne la peine d’approcher le travail des informaticiens, on s’aperçoit qu’ils
travaillent à un haut niveau d’abstraction concrète. Pour réaliser un système
informatique ils doivent d’abord l’imaginer. Puis, compte tenu de la multitude
de contraintes techniques et d’apparentes possibilités, ils doivent le
spécifier, c’est-à-dire le décrire dans des termes précis, non ambigus et
compréhensibles par les personnes qui participent à son développement. Ils
découvrent une véritable matière scientifique, qui émerge des seuls aspects
techniques, électroniques ou mathématisants. L’informatique accumule des
savoirs abstraits aussitôt mis à l’épreuve de la concrétisation. Cette force
conceptuelle rend l’informatique encore plus intéressante car elle la
place au niveau d’une manière de pensée très rigoureuse.
L’informatique n’est plus simplement orientée vers les calculs mais aussi
vers la gestion de l’information, son stockage, sa mise à jour, sa circulation.
La première technologie importante fut celle des systèmes de gestion de bases
de données (SGBD). Depuis c’est l’essor des nouvelles technologies de
l’information qui permettent de stocker l’information sur des supports
diversifiés, de la faire circuler à l’aide de réseaux informatiques, sans fil,
satellitaires et de la prendre en compte sous ses différentes formes :
donnée structurée, document, message textuel ou vocal, image, photo, vidéo.
Au tout début de l’informatique, des personnes appliquaient l’informatique
aux tâches roboratives de la gestion d’entreprise : paye des employés,
traitement des commandes, comptabilité… Elles avaient des technologies frustres
(fichiers COBOL) pour développer ces applications. De plus, elles devaient
affronter une complexité autant organisationnelle qu’informatique sans aide
conceptuelle notamment. Finalement elles fournissaient la solution au problème
en appliquant l’informatique au problème de gestion posé. C’était le temps de
l’informatique de gestion.
L’informatique de gestion est une discipline toute jeune, encore plus jeune
que l’informatique. Alors qu’elle est considérée comme une seule application de
l’informatique au monde de la gestion, elle révolutionne en peu de temps (une
dizaine d’années) les pratiques d’activités dans tous les secteurs en
particulier industriels, commerciaux. En fait ses résultats directs visibles ne
concernent pas la création de nouvelles connaissances en sciences politiques,
économiques, commerciales, industrielles, pédagogiques, mathématiques,
naturelles, juridiques, sociales, psychologiques. Ils ne concernent pas non
plus la création d’entreprise, d’institutions. Ils concernent la constitution
de plates-formes informationnelles informatisées qui permettent l’émergence de
connaissances dans tous les domaines
scientifiques précédemment cités, et la mise en place de pratiques, activités,
entreprises, institutions inexistantes auparavant, alors que d’autres tombent
en désuétude. Ce domaine devient alors beaucoup plus vaste que le seul domaine
de l’informatique de gestion. C’est un véritable carrefour de compétences.
C’est celui des systèmes d’information qui sont utiles pour de nombreuses
personnes aux responsabilités et compétences fort différentes.
Un système d’information est alors une
“construction formée:
·
d'ensembles d'informations, qui sont des représentations partielles de faits
qui intéressent l'institution;
·
de traitements, qui constituent des procédés d'acquisition, de mémorisation,
de transformation, de recherche, de présentation et de communication d'informations;
·
de règles d'organisation, qui régissent l'exécution de traitements informationnels;
·
de ressources humaines et techniques requises pour
le fonctionnement du système d’information” [Bodart 83].
Son enjeu est de comprendre
comment:
·
aménager ce carrefour de compétences entre acteurs et partenaires
concernés;
·
amener l'informatique à être un support pertinent,
indispensable aux activités de l'entreprise ;
·
réaliser une plate-forme informationnelle
informatisée qui se fonde dans les activités des acteurs et partenaires
concernés.
Ce domaine des systèmes d’information est un domaine complexe qui demande
beaucoup de rigueur pour construire la plate-forme informationnelle. Cette
rigueur provient :
·
de l’informatique : il faut spécifier la
plate-forme, comme précédemment pour les développements informatiques;
·
de l’information : il faut spécifier les
informations utiles aux acteurs et partenaires concernés ;
·
des activités : il faut spécifier les
interfaces entre les acteurs et partenaires avec le système d’information.
L’informatique amène à ce carrefour de compétences que représente le
domaine des systèmes d’information, sa force conceptuelle pour permettre à tous
les protagonistes du développement d’un système d’information, de travailler à
un haut niveau d’abstraction concrète. Le principal concept est alors celui de
modèle. « La construction d'un modèle permet d'une part, de représenter un phénomène
en le séparant de son milieu naturel et d'autre part, de simuler la réalité en
incluant tous les éléments qui semblent essentiels à l'explication du mécanisme
du phénomène » [Delobel 73].
Dans la construction d'un modèle pour un système d’information, on est
systématiquement confronté à une difficulté majeure : le "phénomène"
à modéliser n'est pas statique mais dépend du système d’information en
développement. L'objet du modèle contient une part de l'existant, mais aussi
une part imaginée qui correspond au futur système d’information, à sa
réalisation informatique et à son immersion dans les activités de l'entreprise.
En fait, l'objet de tels modèles est le système d’inforamtion lui-même.
Le but de ce livre est de fournir les bases fondamentales conceptuelles de
modèle de systèmes d’information, construites à partir de l’informatique. Ces
bases permettent de participer à des développements de systèmes d’information
qui réclament des travaux de haut niveau d’abstraction concrète.
Le premier chapitre est consacré à l’étude des systèmes de gestion de bases
de données : ce chapitre n’est pas destiné aux spécialistes de
construction de SGBD, mais à des spécialistes de systèmes d’information pour
leur clarifier l’origine des concepts utilisés dans les modèles de systèmes
d’information. Ensuite chaque chapitre présente l’un des concepts fondamentaux
de ces modèles : classe, association, règle d’intégrité, traitements.
Les systèmes
d’information (SI) sont un domaine essentiel de toutes les activités humaines
car la technologie qui les supportent a fourni non seulement une fiabilité et
une puissance de calcul, de stockage et de recherches d’information, jamais
connue auparavant mais aussi de nouveaux espaces de travail, d’échanges, de
manière de coopérer, d’échanger, de concevoir, de se rencontrer, d’acquérir des
connaissances. Comme nos nombreuses pratiques venant des siècles passées sont
fortement contraintes par le support privilégié d’échanges
d’informations : le papier, il
est primordial de connaître les fondements des technologies qui supportent les
SI pour comprendre leurs potentialités mais aussi leurs exigences et les
efforts à consentir pour que les espoirs se concrétisent. Car le support informatique conduit à de nouvelles
pratiques pratiquement inimaginables avec le papier. Ce sont de véritables plates-formes d’activités humaines
qui sont en cours de construction.
Cette
introduction présente la technologie informatique qui a été et reste toujours
la technologie de référence des SI : celle des bases de données.
Un exemple :
gestion d’une entreprise de transports publics
L’entreprise
« GVA » s’occupe des transports publics de la ville d’Evèneg. Elle
désire se doter d’un système informatique pour la gestion de son réseau.
Celui-ci comprend des lignes, des véhicules ainsi que des chauffeurs.
Elle aimerait un
SI qui puisse prendre en compte des faits comme :
·
le chauffeur « Boubou » est en congé le lundi
30 octobre ;
·
le 31 octobre, il assure la ligne 2 avec le véhicule 56.
Elle aimerait que
son personnel puissent trouver les réponses à des questions du type suivant
grâce au SI :
·
un véhicule doit-il toujours assurer la même ligne?
·
Qui a assuré la ligne C le 3 octobre entre 16h et 18h?
Elle aimerait
aussi que le SI fournisse un support efficace pour faire face à des situations
inhabituelles voire critiques de type :
·
Boubou est malade aujourd’hui ; comment peut-on le remplacer ?
·
Le tram de la ligne 12 est bloqué par un accident ; cela va prendre du
temps ; comment aménager une solution de secours ?
Elle aimerait que
le SI tienne compte d’événements comme :
·
le véhicule 124 est enlevé de la circulation.
Elle aimerait que
le SI prenne en compte des règles comme :
·
un chauffeur a un seul permis de conduire ;
·
il est compétent pour plusieurs types de véhicule.
Ce sont ce genre
de services que va rendre la technologie des bases de données. Mais pour avoir
les qualifications requises pour construire de telles bases de données il faut
appréhender une complexité formée de :
·
technologies informatiques et surtout des systèmes de gestion de bases de
données ;
·
conceptualisation des schémas de bases de données, des traitements des
données, des interfaces avec les acteurs de l’entreprise
« GVA » ;
·
organisation des activités humaines sous-jacentes à l’utilisation intensive
de la base de données dans le cadre de différents processus organisationnels.
Avant les bases
de données les institutions possédaient des fichiers manuels sur support papier,
qui contenaient énormément de redondance et qui étaient très difficile de
maintenir-à-jour. Les bases de données ont introduit le principe qu’une donnée
serait stockée dans un seul endroit principal, qu’elle y serait mise–jour
continuellement et qu’elle serait facilement accessible à tous les acteurs qui
en auraient besoin.
Ainsi les bases
de données servent principalement à :
·
stocker de gros volumes de données/informations ;
·
les faire partager
par une communauté de personnes. Les données une fois stockées dans une base de
données sont à priori atteignables par toutes les personnes ayant accès à la
base ; de plus ces personnes peuvent modifier ces données, comme dans
l’exemple GVA, modifier l’affectation du chauffeur Boubou à une ligne, pour un
jour donné ; dès que cette modification est apportée à la base elle est
visible par toutes les personnes concernées.
·
gérer l’accès à ces données ; dans de nombreux cas, si toute donnée dans
la base est visible et modifiable par n’importe quelle personne à n’importe
quel moment, alors l’institution ne peut plus fonctionner autant à cause de
questions de confidentialité que de simples questions de bon
fonctionnement : dans l’exemple GVA, quand une personne modifie
l’affectation du chauffeur Boubou à une ligne, encore ne faut-il pas qu’en même temps une
autre personne n’accorde un jour de congé à Boubou !
·
gérer des informations
cohérentes et non-redondantes ; si Boubou change d’adresse,
il suffit de modifier cette adresse dans un seul endroit de la base. De plus
quand on rentre des données dans la base, il y aura des mécanismes de
validation de règles d’intégrité qui vont se déclencher, garantir l’intégrité
des nouvelles données et assurer leur cohérence par rapport aux données
contenues dans la base. Ainsi si l’on
veut affecter Boubou à une ligne tel jour, faut-il s’assurer qu’il n’est pas en
congé ce jour-là
Du
point de vue informatique, une base de données est structurée à l’aide de classes/relations
munies d’attributs et pour chaque
attribut d’un domaine. Le prédicat d’une classe/relation donne le
sens des associations entre les attributs. Un objet d’une classe prend une ou plusieurs valeurs pour chaque attribut
de la classe, ces valeurs devant
appartenir au domaine de l’attribut.
Soit la classe
Affectation munie des attributs NomChauffeur, NoLigne, NoVéhicule :
Affectation(NoChauffeur, NoLigne, NoVéhicule) et de prédicat : un chauffeur de tel nom est affecté à une
ligne de tel numéro et va conduire un véhicule de tel numéro.
Voici des
données : NomChauffeur = {Boubou, Lulu} ;
NoVéhicule = {25,4,56,86} ;
NoLigne
= {A,2}.
Voici
des objets d’Affectation :
NomChauffeur |
NoLigne
|
NoVéhicule
|
Boubou |
2 |
56 |
Boubou |
A |
4 |
Lulu |
2 |
86 |
Par application
du prédicat d’Affectation, ces objets signifient que :
·
le chauffeur Boubou assure la ligne 2 avec le véhicule
56 ;
·
le chauffeur Boubou assure la ligne A avec le véhicule
4 ;
·
le chauffeur Lulu assure la ligne 2 avec le véhicule 86.
Un Système de Gestion de Bases de Données (SGBD)
est un système générique qui a pour fonction le stockage, l’accès et la
manipulation de grandes masses de données. Il est générique car il ne
s’intéresse pas à un domaine particulier d’activités mais au contraire
construit toute une plate-forme logicielle indépendante de cadres d’utilisation
particuliers.
Un SGBD considère
qu’une donnée/information/objet prend un lieu dans l’espace géré par le SGBD et
le conserve pendant toute la durée de son existence.
Toute donnée doit
avoir un nom qui permet de la
différencier des autres données. Une fonction essentielle d’un SGBD est de
permettre à tout moment de faire correspondre à un nom d’une donnée son lieu de stockage.
Figure 1.
Espaces d’un SGBD |
Ainsi que l’on
soit développeur ou simple acteur, on ne peut retrouver une donnée que par son
nom (1). Le SGBD avec ce nom connaît le domaine de cette donnée : il sait
le nombre d’octets qui correspondent à cette donnée, ainsi que le mode
d’interprétation de ces octets (faut-il les interpréter en tant que chaînes de
caractères, entiers, réels, dates…). Le SGBD avec ce nom calcule le lieu de
stockage de la donnée (2) puis va rechercher dans la mémoire l’ensemble des
octets qui lui correspondent (3) et ramène ces octets dans l’interface ;
grâce au domaine de la donnée il interprète les octets en termes
compréhensibles aux acteurs (4) et leur fournit le résultat (5).
Ainsi existe-t-il
deux grands thèmes dans la technologie des bases de données :
·
celui des fonctionnalités autant externes qui vont permettent les échanges avec
l’extérieur qu’internes qui vont assurer la gestion des données dans l’espace
de stockage géré par le SGBD ;
·
celui du modèle de données qui va gérer l’espace des noms.
La figure
suivante montre que le SGBD sert d’intermédiaire entre, d’une part, les
demandes de données qu’elles proviennent d’un programme en cours d’exécution,
ou d’une personne se servant d’un terminal ou d’un PC, et d’autre part les zones informatiques de
stockage des données.
Figure 2.
SGBD et son environnement |
Voici une liste
des principales fonctionnalités que doit posséder un SGBD.
C’est la
fonctionnalité la plus connue d’un SGBD, celle qui permet d’interroger une base
de données et d’en modifier les données (insertion,
suppression, modification de données), le tout à l’aide d’un langage
générique (indépendant d’un domaine
d’activités particulier) comme le
langage SQL dans le monde des SGBD relationnels, qu’il est indispensable
d’apprendre. Elle permet aussi de :
·
programmer la recherche, et non pas seulement poser des
interrogations, une par une ;
·
utiliser des langages plus complexes en fonction de
domaines particuliers, comme les domaines géographiques, temporelles…
·
coupler le SGBD avec des interfaces visuelles, tactiles,
vocales...
·
exploiter les liens entre les données
·
dériver de nouvelles informations à partir des données
stockées
·
mettre-à-jour les données
·
programmer ces mises-à-jour.
Cette
fonctionnalité des SGBD est sans doute celle qui a le plus contribué au succès
des bases de données dans le monde des affaires.
Elle garantit que
les modifications de la base de données vont
respecter les coutumes du monde vivant.
Pour
cela elle permet aux concepteurs de bases de données de définir des règles d’intégrité qui sont des
propriétés qui doivent être vérifiées par les données et qui peuvent être
vérifiées par des programmes.
Dans
le cas de l’entreprise GVA, voici l’exemple d’une règle d’intégrité : un chauffeur ne doit pas conduire plus de
40h par semaine.
Un
très grand intérêt d’un SGBD est qu’il permet à tout un ensemble d’acteurs de
partager de mêmes données d’une base de données. On peut même dire qu’ à partir
du moment où une personne a un accès à une base de données, alors il a accès à
toutes les données de la base, à moins que les responsables de la
base ne décident que pour certaines données, seules des personnes autorisées
pourront les consulter ou les mettre-à-jour.
C’est le rôle de cette
fonctionnalité des SGBD. Elle gère les droits
d’accès des personnes aux données de la base en
·
ne rendant accessibles certaines données qu’aux personnes autorisées,
·
ne rendant modifiables certaines données qu’aux personnes autorisées,
·
définissant les données à protéger
Ainsi dans
l’exemple GVA, les usagers n’ont pas à connaître les horaires des chauffeurs.
Comme déjà
mentionné un grand intérêt des SGBD est celui de permettre plusieurs demandes
de travail en même temps sur une même base de données. De telles demandes
proviennent de personnes et/ou de programmes.
Cette nouvelle
fonctionnalité des SGBD
·
détecte les accès simultanés aux mêmes données, ou conflits,
·
les traite quand ils surviennent (ex : en mettant des demandes d’accès en attente),
·
cherche même à les éviter en analysant les demandes
d’accès.
Ainsi
pour GVA, il pourrait y avoir plusieurs demandes d’affectation de chauffeurs à
des lignes simultanément.
Les
bases de données sont devenues des ressources informationnelles incontournables
pour le bon fonctionnement d’une institution. Mais elles sont gérées par des
SGBD dans des environnements techniques qui peuvent tomber en panne ou être
défectueux. Compte tenu des enjeux économiques les SGBD disposent d’une autre
fonctionnalité qui :
·
assure le redémarrage du système en cas d’incident logiciel ou matériel,
·
remet la base de données dans un état satisfaisant.
Dans un SGBD
toute donnée n’est accessible que par son nom. Aussi tout SGBD doit-il posséder
des règles pour donner des noms aux données : ces règles sont consignées
dans le modèle de données du SBGD.
Un tel modèle de données a en fait un double objectif :
·
celui de permettre de désigner une donnée par son nom,
·
celui de permettre de calculer l’adresse de stockage d’une donnée par son
nom.
La communauté des
bases de données a rapidement compris qu’il existait en fait trois niveaux
technologiques dans un SGBD :
·
le niveau interne qui est en
contact direct avec l’espace de stockage des données et avec les système
d’exploitation et de gestion de fichiers de l’ordinateur hôte ; c’est
notamment à ce niveau que sont résolus les correspondances entre les noms des
données et leurs lieux de stockage ;
·
le niveau conceptuel qui doit se
conformer au modèle de données du SGBD ;
·
le niveau externe propre aux
programmes particuliers et aux interfaces.
A chacun de ces
niveaux correspondent des schémas qui sont au monde des bases de données ce que
sont les plans au monde de l’architecture, avec quand même une
différence : les utilisateurs des
schémas ne sont pas seulement des personnes, ce sont aussi des programmes du
SGBD qui s’en servent pour exploiter les données de la base.
Figure 3.
Les niveaux d’un SGBD |
Les concepteurs
d’une base de données doivent d’abord fournir un schéma conceptuel par un
effort de modélisation du domaine
d’activités. Ensuite ils peuvent construire des schémas externes si
nécassaire. C’est le SGBD qui va construire le schéma interne.
Ainsi, dans le
monde des bases de données, il faut d’abord fournir un schéma conceptuel avant
de pouvoir stocker la moindre donnée.
Modèles de données
Très
vite vous allez vous apercevoir qu’il existe deux mondes complémentaires qui
ont des recouvrements conceptuels importants et pourtant qui ont des finalités
et des logiques différentes :
·
celui de la technologie des SGBD, un monde purement informatique, où les
maîtres mots sont performance, sûreté,
sécurité et fiabilité, répartition et réseau ;
·
celui de la conception et de l’évolution de bases de données gérées par des
SGBD, où les maîtres mots sont utilité,
intégrité, sûreté, sécurité, compréhension, diversité, formation,
réorganisation…
La notion de
modèle est commune à ces deux mondes, mais du côté informatique il s’agit
d’avoir un schéma pour faire la correspondance de l’espace des noms avec
l’espace de stockage et assurer les fonctionnalités du SGBD, alors que du côté
de la conception il s’agit de l’interpénétration des activités du monde vivant avec
le monde informatique. Bien qu’on utilise à peu près le même genre de modèles
dans ces deux mondes, il ne faudra pas oublier que ces deux mondes n’ont ni les
mêmes objectifs ni les mêmes exigences.
Pour le monde de
la conception, un modèle de données est
un ensemble de concepts et des notations qui permettent de décrire une
vision d’un domaine d’activités. Pour le monde des SGBD, c’est un ensemble de
concepts et des notations qui permettent de faire facilement la correspondance
entre le nom d’une donnée et son lieu de stockage.
Voici une liste
de types de modèles pour le monde de la conception : Entité-Association,
Relationnel, Entity-relationship, Merise, Objet, UML, Z ...
Voici les 4 types
fondamentaux de modèles de SGBD : hiérarchique, réseau, relationnel, objet et
un rapide historique de l’arrivée de ces modèles :
1960 : les modèles hiérarchiques,
1970 : les modèles réseaux,
1980 : les modèles relationnelles,
1990 : les modèles objets.
Soit l’exemple
GVA avec des chauffeurs (C) qui ont des permis (P) et qui conduisent des
véhicules (V).
Dans le modèle hiérarchique, il faut choisir une racine, comme par exemple
Chauffeur et ensuite des segments comme Véhicule et Permis. Une donnée de
Véhicule doit obligatoirement être reliée à une donnée de Chauffeur et si un
véhicule est conduit par plusieurs chauffeurs alors il faudra dupliquer les
informations de ce véhicule autant de fois qu’il y a de chauffeurs (redondance de données).
Dans le modèle réseau, les sommets jouent les
mêmes rôles ; ainsi on va pouvoir stocker les chauffeurs , les véhicules
et les permis séparément et ensuite relier les données de chauffeurs et celles
de véhicules quand les chauffeurs conduisent les véhicules ; la redondance
précédente est ainsi évitée (normes CODASYL). Bien sûr le modèle réseau est
plus intéressant que le modèle hiérarchique, mais il a fallu d’abord résoudre
les nombreux problèmes du niveau interne du SGBD pour que les concepteurs d’un
SGBD puissent construire avec succès un SGBD réseau.
Ensuite arrive le
modèle relationnel qui fournit toute
une régularité dans le modèle conceptuel et qui permet aussi de faire une nette
différence entre les niveaux interne et conceptuel d’un SGBD.
Une relation est
une représentation d’une association particulière entre certains constituants
du domaine d’activités, appelés attributs
de la relation. De plus une relation est construite à l’aide d’un identifiant ou d’une clé qui permet de distinguer toutes ses
données les unes des autres.
Ainsi dans
l’exemple GVA, Chauffeur(NoCh//Nom,Prénom,Adresse) désigne une relation de nom
Chauffeur, formée sur les attributs NoCh, Nom, Prénom, Adresse, et de
prédicat : un chauffeur ayant pour numéro
NoCh, pour nom «Nom», pour prénom «Prénom» et pour adresse «Adresse» ;
l’identifiant ou la clé de Chauffeur est NoCh, ce qui signifie qu’il ne peut
pas avoir deux données de Chauffeur avec le même numéro de chauffeur.
Les données d’une
relation sont appelées des entités
de la relation dans le modèle relationnel.
Ainsi le nom d’une entité de Chauffeur dans le
modèle relationnel se compose du nom de la relation Chauffeur et d’une valeur
prise pour la clé de Chauffeur : NoCh.
Enfin dans le
modèle objet, la définition d’une classe (relation) comporte non
seulement des attributs mais aussi des méthodes
qui peuvent être appliquées sur les données des classes appelées des objets de la classe.
Ainsi peut-on
envisager la classe Chauffeur(NoCh//Nom,Prénom,Adresse) avec la méthode
ChangerAdresse.
Le modèle objet
informatique comprend de nombreux autres concepts comme association, héritage,
agrégation…
Il existe
d’autres différences entre le monde relationnel des SGBD et celui des SGBD
objet, surtout au niveau des schémas
internes ; elles dépassent le propos de ce chapitre.
Ce sont les
modèles relationnel et objet qui sont utilisés dans la suite de cet ouvrage.
Ils reposent tous
les deux sur les concepts principaux suivants :
·
des classes (modèle objet) ou relations (modèle
relationnel),
·
des données qui sont des objets ou des entités (comme des
chauffeurs, des véhicules, des objets des classes Chauffeurs, Véhicules,
Lignes)
·
des associations entre des classes (modèle objet) ou des
relations (modèle relationnel) qui permettent de stocker des faits comme
ceux-ci : un chauffeur assure telle
ligne en conduisant tel véhicule ...
La classification
est définie dans les encyclopédies comme :
·
l'action de distribuer par classes, par catégories,
·
l'action de répartir des espèces vivantes animales ou végétales en
catégories hiérarchisées selon leurs caractères communs,
·
la distribution régulière et méthodique de diverses choses suivant un
certain plan.
Elle
« provient d'un besoin universel pour décrire l'uniformité d'une
collection d'instances. C'est l'activité fondamentale des scientifiques pour
organiser les connaissances en disciplines scientifiques, des programmeurs pour
organiser les domaines de connaissances et les comportements" [WEG87].
Dans le monde
informationnel, une classe désigne une structure commune abstraite d’un
ensemble d’objets ou d’entités ou d’occurrences de la
classe, qui vont représenter des éléments du monde ayant des propriétés
communes de comportement, des caractéristiques communes et un canevas commun de
description, à l’aide duquel chaque objet d’une même classe se distingue des
autres objets de la même classe.
Dans ce livre, nous utilisons le terme de classe à
la fois pour le concept de classe de l'approche objet et pour le concept
de relation du monde relationnel. Nous ne faisons donc aucune
distinction entre ces deux concepts dans la mesure où nous considérons qu'ils
représentent tous les deux les résultats d'une classification. Il y a deux
types de notations qui peuvent êtres utilisés de façon équivalente. La
première, basée sur la notation relationnelle, est textuelle alors que la
seconde comme dans des approches relationnelles [Léonard 88] ou
entité-association ou entity-relationship comme MERISE [Tardieu 83], ou objet
UML [Booch 99], est graphique. Nous utilisons principalement la notation
textuelle qui nous semble la plus simple à utiliser, tout en donnant les
équivalents graphiques, notamment en UML, lorsqu’ils existent.
L'entreprise GVA
s’occupe des transports publics de la ville d'Evèneg. Elle désire se doter d'un
système informatique pour la gestion de son réseau. Celui-ci comprend des
lignes, des véhicules ainsi que des chauffeurs. Voici un premier schéma de
classes/relations correspondant à ce domaine d’activités. Le but de ce chapitre
est de présenter tous les concepts sous-jacents à ce schéma.
Classes / relations
CHAUFFEUR (Nom, Prénom, NoAVS, Adresse,
DateNaissance, Sexe, TotalHeures)
Pour chaque
chauffeur, identifié soit par son numéro AVS soit par son nom et prénom, on
conserve son adresse, sa date de naissance ainsi que son sexe. L'entreprise
“GVA” désire également conserver le nombre total d'heures de conduite de chaque
chauffeur.
PERMIS (NoAVS,
Catégorie, DatePermis)
Il existe 3
catégories de véhicules: tramway, bus et trolleybus. Chaque chauffeur est
compétent pour une ou plusieurs catégories de véhicules. Lorsqu’un chauffeur
réussit un examen de conduite pour une catégorie de véhicules, on conserve la
date d'obtention du permis.
VEHICULE
(NoVéhicule, Catégorie, Marque, NoChâssis, NoMoteur, DateCirculation)
Chaque véhicule
est identifié par un numéro. On lui associe sa catégorie, sa marque, son numéro
de châssis, son numéro de moteur, ainsi que sa date de mise en circulation.
LIGNE (CodeLigne,
Catégorie, TypeLigne, ArrêtDépart, ArrêtArrivée)
Le réseau de
circulation est composé de lignes. Chaque ligne est identifiée par un code
pouvant être soit un numéro, soit une chaîne de caractères (ex. ligne
AFF-VEHICULE
(NoVéhicule, Date, StatutVéhicule, CodeLigne, StatutAffectation)
L'affectation des
véhicules aux différentes lignes du réseau s'effectue quotidiennement. Ainsi,
un véhicule est associé pour un jour donné à une et une seule ligne; il est
évident que plusieurs véhicules peuvent être engagés sur une même ligne le même
jour. Il faut cependant souligner qu'un véhicule ne peut être utilisé sur une
ligne que si celui-ci est en état de marche le jour désiré. En effet, chaque
jour, un véhicule est soit disponible soit en réparation; lorsqu'un véhicule
est affecté à une ligne, il est soit actif (mis en service régulier), soit de
réserve. Bien entendu, la catégorie du véhicule doit correspondre à la
catégorie de la ligne: Il est impensable qu'un tramway puisse desservir une
ligne de trolleybus.
AFF-CHAUFFEUR
(NoAVS, Date, StatutChauffeur, NoSérie)
L'entreprise GVA
désire également gérer l’emploi du temps quotidien des chauffeurs. Un
chauffeur, pour un jour donné, est soit en congé (il ne peut donc être employé
ce jour-là), soit en service régulier, soit de réserve. De plus, pour un jour
donné, un chauffeur en service régulier
ne peut être affecté qu’à une et une seule série.
TRANCHE-SERIE
(NoSérie, CodeLigne, HeureDébut, HeureFin)
Une série est
identifiée par un numéro et elle concerne un ensemble de lignes distinctes
(c’est-à-dire une série ne peut pas contenir la même ligne plus d'une fois).
Pour chaque ligne d'une série, on connaît l'heure de début d'activité et
l'heure de fin d'activité.
L'exemple
ci-dessous illustre le cas des séries : la série 328 concerne les lignes 3, 4
et C. Le chauffeur “Boubou”, affecté à cette série le 24 juin 1991 débute son
travail à 6h12 sur la ligne 3 et le termine à 21h00 sur la ligne C. Il
travaille ainsi 7 heures et 13 minutes en tout.
HEURE-CHAUFFEUR
(NoVéhicule, Date, NoAVS, NbHeures)
Chaque jour, le
nombre d'heures de conduite d’un véhicule, effectuées par un chauffeur, est
stocké dans la base. Lorsqu'un chauffeur est en réserve, il peut être utilisé
pour conduire un véhicule si nécessaire. Dans ce cas, il devient chauffeur de
remplacement et on l'affecte directement à un véhicule et non à une série.
·
les concepts associés aux classes,
·
l’identification des objets d’une même classe,
·
la forme normale de classes,
·
la prise en compte des classes dans le monde informatique avec leurs
méthodes stockage,
·
les principales opérations définies sur les classes et objets,
·
les types de règles d’intégrité définies sur une classe,
·
la nécessaire relativité des qualités demandées à la définition d’une
classe.
Les objets d’une classe C partagent en commun :
·
les attributs de C, chacun associé à un domaine de
valeurs : pour chaque attribut, ils prennent une ou plusieurs valeurs de
son domaine ;
·
des méthodes qui leur transforment leurs valeurs pour
certains attributs ;
·
des états qu’ils prennent suivant les méthodes ou les
traitements qui les ont transformés;
·
des règles d’intégrité qu’ils doivent vérifier :
elles garantissent leur intégrité et leur cohérence mutuelle. Compte tenu de leur importance, elles
seront présentées dans un chapitre séparé.
Chaque
objet o de C a un identificateur d’objet (oid(o))
qui permet de le distinguer des autres objets de C ainsi que des objets des
autres classes.
Nous présentons
tous ces concepts en détail dans la suite de cette section.
Si A est un
attribut de C, et o un objet de C, alors o[A] (autre notation
usuelle : o.A) désigne les valeurs que prend l’objet o pour
l’attribut A. Le domaine d’un attribut, dom(A), définit l’ensemble des valeurs
que les objets peuvent prendre pour A. Tout attribut a un et un seul domaine.
Tout attribut a
un nom qui permet de le distinguer de tous les autres attributs de
toutes les classes. C+ désigne l’ensemble des attributs de C.
Par exemple, pour
la classe VEHICULE, un véhicule est défini par son numéro de châssis, sa
marque, son numéro de véhicule, son numéro de moteur, sa catégorie (bus,
trolley, tram etc.) et ses dates de mise en circulation. Alors VEHICULE+ =
{NoVéhicule, NoChâssis, NoMoteur, Marque, Catégorie, DateCirculation}.
Un domaine
D est un ensemble non-vide de ses valeurs. L’écriture a Î D signifie que la
valeur a appartient au domaine D. Un domaine a un nom qui permet
de le distinguer de tous les autres domaines.
D est un domaine composé
s'il est défini à l’aide de plusieurs domaines D1… Dn.
Son ensemble est le produit cartésien des ensembles de D1… et de Dn,
diminué éventuellement d'éléments vérifiant une condition précise.
Le type d'un domaine indique les
opérations qui sont définies sur ses valeurs. Il faut toujours préciser le type
d’un domaine. Voici la liste des opérations définies dans D suivant son type :
·
type texte : aucune opération ;
·
type mot : les opérations de comparaison "égalité" et
"différence" ;
·
type mot ordonné : en plus des opérations "égalité"
et "différence", les opérations de comparaison "inférieur",
"supérieur" ;
·
type numérique : en plus des opérations précédentes, les opérations
d'addition et de soustraction ; on peut préciser ce type par entier,
entier positif, décimal, réel, etc.…
·
type booléen : D ne contient que deux valeurs (vrai, faux) et
les opérations de l'algèbre de Boole (non, et, ou) sont définies sur
D ;
·
type monôme : D est composé de plusieurs domaines de type
booléen et les opérations booléennes s’appliquent.
Pour des domaines
de type numérique et de types mot et mot ordonné, il peut être nécessaire de
préciser l’unité relative aux valeurs du champ (Km, kg, g, mn...).
Pour définir
un domaine, on précise ses valeurs
·
par énumération dans le cas de domaines de type mot ou mot ordonné ou
booléen,
·
ou avec des intervalles de définition s’il est de type numérique ou mot
ordonné,
·
ou par un formalisme mathématique ou algorithmique.
Exemples de
domaines fréquemment utilisés :
dom NOJOUR : mot ordonné [1,31].
dom MOIS : mot {janvier, février, mars, avril, mai, juin,
juillet, août, septembre, octobre, novembre, décembre}.
dom ANNÉE : mot ordonné [1900, -].
dom DATE : mot ordonné composé de NOJOUR, MOIS, ANNÉE moins
"jours farfelus". "jours farfelus" est le résultat d'un
algorithme qui fournit l'ensemble des jours farfelus comme le mardi 30 février
2001.
dom HEURE : mot ordonné [0,23].
dom MINUTE : mot ordonné [0,59].
dom HORAIRE : mot ordonné composé d’HEURE MINUTE.
dom DURÉE-S : numérique entier unité seconde.
dom DURÉE-MN-S: composé de numérique
entier unité minute et de DURÉE-S.
dom DURÉE-HMNS: composé de numérique
entier unité heure et de DURÉE-MN-S.
Attribut composé
Un attribut A est
composé s'il est défini à partir de plusieurs attributs ou si son
domaine est un domaine composé. Son domaine D est un sous-ensemble du produit
cartésien des domaines qui le composent; ce sous-ensemble est déterminé par un
processus algorithmique (éventuellement ce sous-ensemble est égal au produit
cartésien lui-même).
Dans notre
exemple GVA, l’attribut DateCirculation a pour domaine DATE qui est un mot
ordonné composé d’un numéro de jour, d’un mois et d’une année.
Si a désigne une
valeur d’un attribut A composé des attributs A1… An,
alors les notations a[A1] désigne la valeur prise par a pour
l’attribut A1. Maintenant si l’attribut A admet un domaine composé
des domaines D1… Dn alors a[D1] désigne la
valeur prise par a pour D1. Ainsi DateCirculation[NOJOUR] donne le
jour de circulation d’un véhicule.
Un attribut, dont
le domaine est une classe C’, porte le nom de l’attribut d’identificateur
d’objet de C’ : oidC’, sauf s’il existe plusieurs associations de la
classe C avec C’ (voir chapitre suivant).
Attribut monovalué et attribut multivalué
Un attribut de C
est monovalué pour C si un objet de C ne peut prendre qu’une valeur pour
cet attribut. Il est multivalué pour C si un objet de C peut prendre
plusieurs valeurs pour A.
Ainsi pour la classe VÉHICULE, seul l’attribut
DateCirculation est multivalué : un objet de Véhicule peut prendre
plusieurs valeurs pour DateCirculation.
Notations
possibles :
Pour représenter la multivaluation d’un attribut,
on peut étendre la notation relationnelle standard, en introduisant le symbole*
DateCirculation* signifie qu’il y a plusieurs valeurs pour la date de
circulation.
VÉHICULE
(NoVéhicule, Catégorie, Marque, NoMoteur, DateCirculation*).
Dans UML [Booch
99], la valuation d’un attribut est donnée entre crochets. Le fait que la date
de circulation puisse avoir zéro ou plusieurs valeurs se note par :
DateCirculation[0..n]. La valuation non précisée, l’attribut est monovalué.
Groupe d’attributs
Un groupe
d’attributs est formé d’un ensemble d’attributs : il peut être
monovalué ou multivalué. Dans l’exemple suivant :
VÉHICULE
(NoVéhicule, Catégorie, Marque, (NoMoteur, DateCirculation)*), (NoMoteur,
DateCirculation) forme un groupe multivalué. Un objet de Véhicule peut prendre
alors plusieurs valeurs composées d’une valeur pour Moteur et d’une valeur pour
DateCirculation.
Valeur
obscure, objet obscur
Pour chaque attribut A de C, il faut indiquer si
un objet de C peut prendre une valeur obscure pour A. Une valeur
obscure correspond à une valeur inconnue ou une valeur impossible. Ainsi
Notations
possibles :
VÉHICULE
(NoVéhicule-, Catégorie, Marque, NoChâssis, NoMoteur,
DateCirculation-):
les attributs
NoVéhicule et DateCirculation admettent des valeurs obscures.
Dans UML [Booch
99], la valeur obscure correspond à une valuation de 0. Comme pour la
multivaluation, on peut donc préciser entre crochets, la valuation d’un
attribut : NoVehicule[0..1], DateCirculation[0..n].
Un objet o
de C est clair si pour tout attribut A de C, o prend une valeur
claire. Il est obscur s'il existe au moins un attribut pour lequel il
prend une valeur obscure.
Attribut permanent
Un attribut A
d’une classe C est permanent, si la valeur claire prise pour A par tout
objet de C ne peut être modifiée.
Notation possible : VÉHICULE (NoVéhicule-=,
Catégorie=, Marque=, NoChâssis=, NoMoteur,
DateCirculation-) : un objet de Véhicule conserve les
valeurs prises pour NoVéhicule, Catégorie, Marque et NoChâssis, alors que ses
valeurs pour NoMoteur et DateCirculation sont modifiables.
État
Un état
est un attribut qui est mis à jour seulement par des méthodes ou par des
transactions.
Un état donne une
trace des travaux effectués sur un objet.
Dans l’exemple
précédent, si
DateCirculation est un état contrôlé par les méthodes activer et désactiver,
alors activer (véhicule) fait passer sa date de circulation d’une valeur
obscure à une valeur claire la date du jour, alors que désactiver (véhicule)
fait passer sa datecirculation d’une valeur claire à une valeur obscure. Il
faut compléter la définition de la classe VÉHICULE :
VÉHICULE
(NoVéhicule-=, Catégorie=, Marque=,
NoChâssis=, NoMoteur, DateCirculation-), où la
notation italique DateCirculation signifie que l’attribut
DateCirculation est un attribut de type état.
Une méthode d’une
classe C est une action qui concerne un objet ou un ensemble d’objets de C, qui
permet de créer, supprimer, modifier ou rechercher des objets de C.
Exemple
de méthodes de la classe Véhicule :
VÉHICULE
(NoVéhicule-=, Catégorie=, Marque=,
NoChâssis=, NoMoteur, DateCirculation-)
méthode créer (véhicule :
Véhicule),
méthode activer (véhicule :
Véhicule),
méthode supprimer (véhicule
: Véhicule),
méthode désactiver
(véhicule : Véhicule),
méthode contrôler (véhicule
: Véhicule),
méthode réparer (véhicule : Véhicule).
Les méthodes créer
/ supprimer permettent de créer / supprimer un objet de la classe Véhicule.
Les méthodes activer / désactiver l’objet o permettent de considérer que
le véhicule représenté dans la classe par l’objet o est désormais
disponible/indisponible au service.
La méthode contrôler
s’applique sur un objet o si le véhicule est soumis à un contrôle
technique. La méthode réparer s’applique sur un objet o si le
véhicule est soumis à une réparation.
Notations
possibles :
La notation relationnelle ne permet
pas de représenter les méthodes associées à une classe. Néanmoins, il est
possible de les lister sous la déclaration de la classe comme nous l’avons fait
précédemment. En UML, une classe peut se représenter graphiquement ainsi, en
trois parties (exemple de la classe VEHICULE) :
Une classe
est formée à l’aide d’un prédicat noté ||C|| formé sur les attributs de C+ qui
fournit le sens de l’association de ces attributs dans C. Par exemple,
|| VÉHICULE ||
= pour chaque véhicule
identifié soit par son numéro de châssis soit par son numéro de moteur soit par
son numéro de véhicule, on connaît sa catégorie, sa marque et ses dates de mise
en circulation.
Un n-uplet
de C est un élément du produit cartésien des domaines des n attributs de
C, augmentés de la valeur obscure pour les attributs l’autorisant. Un objet
o de la classe C est un n-uplet de C qui valide son prédicat : ||C||(o) = vrai. Ainsi <GE 334 566, bus,
Chausson, ?, ?, ?, ?, 10/01/01> est le n-uplet de la
classe VÉHICULE (NoVéhicule-=, Catégorie=,
Marque=, NoChâssis=, NoMoteur, DateCirculation-)
pour lequel le numéro de véhicule est GE 334 566, la catégorie bus, la marque
Chausson et la date de circulation le 10/01/01 (les numéros de châssis et de
moteur étant indéfinis).
Remarque: le fait qu'un n-uplet du produit
cartésien soit ou ne soit pas un objet de la classe C ne relève d'aucun
processus algorithmique : ce sont les personnes responsables de
l’alimentation de la base qui en prennent la responsabilité. C’est une
différence fondamentale entre les concepts de classe et d’attribut composé.
Dans l’exemple
précédent, si GE 334 566
est une valeur de NoVéhicule, Chausson une valeur de Marque, alors o=<GE
334 566, bus, Chausson, ?, ?, ?, ?, 10/01/01> est bien
un n-uplet du produit cartésien avec « ? » pour la valeur
obscure ; o est un objet de Véhicule seulement si une personne a
décidé de stocker o dans la base.
Notation:
Si o est
un objet de C, o[Ai] (ou o.Ai) désigne la valeur prise
par o pour l’attribut Ai.
Si S+ désigne
un sous-ensemble de R+, o[S+] (ou o.S+)
désigne les valeurs prises par o pour les différents attributs de S+.
La notation o Î C signifie que le
n-uplet o du produit cartésien des domaines des attributs de C est un
objet de C.
Une instance d'une
classe C est un ensemble d'objets de cette classe que nous notons iC (et
éventuellement plus simplement C s'il n'y a pas d'ambiguïté possible avec la
classe C elle-même). Dans le monde des SGBD, à chaque classe, il correspond une
seule instance. Par contre généralement il faut considérer plusieurs instances
d’une même classe dans les phases d’analyse, de modélisation et de
spécification de bdd.
Une instance
d'une bdd formée des classes C1... .Cn est un ensemble
d’instances un par classe : {iC1... i Cn}.
Comment retrouver un objet parmi tous les
objets de sa classe?
·
Une première réponse, technologique,
attribue à toute classe C un attribut particulier l’identificateur d’objet,
oidC : le SGBD attribue à tout objet de la classe une valeur
distinctive pour cet attribut. Cet identificateur facilite l’écriture du code
de n’importe quel SGBD. Mais cette réponse n’est évidemment pas satisfaisante
pour les personnes qui vont travailler avec la bdd : avec cette seule réponse,
elles ne pourraient accéder aux données qu’au travers de leurs oids, non par
leur sémantique (comme c’était le cas dans les années 60, où toute personne
désireuse de retrouver des informations devaient franchir les marécages de
codifications ténébreuses…).
·
Or, justement, les SGBD ont pour but de
permettre l’accès aux données par leur nom. Pour cela il faut identifier les
objets d’une classe à l’aide de ses attributs : c’est la réponse
informationnelle et tous les SGBD l’implémentant, comme les SGBD relationnels,
font gagner beaucoup de temps autant dans le développement de la base que dans
son exploitation.
Dans le monde relationnel comme dans celui de l'objet, la
notion d'identifiant ou de clé est donc fondamentale. Nous distinguons ici deux
types d'identifiant suivant leur caractère obligatoire.
Un ensemble d'attributs K de C forme un identifiant
obligatoire (ou clé obligatoire) de C si :
·
tous les attributs de K sont
monovalués, sans valeur obscure, permanents, avec des domaines dont aucun n’est
de type texte;
·
deux objets o et o’ de C ne
peuvent prendre les mêmes valeurs pour K : o[K] ¹o’[K] ;
·
K est minimal : il n’existe
aucun sous-ensemble de K vérifiant la propriété précédente.
C’est la définition de la clé d’une relation
dans le monde relationnel. Une clé obligatoire permet de distinguer entre eux tous
les objets d'une même classe C suivant les valeurs qu'ils prennent pour les
attributs formant cette clé.
Nous supposons que toute classe admet au moins une clé, en plus de la clé
triviale formée par l’identificateur d’objets : dans un cas extrême cette clé
est formée de tous les attributs de la classe. Une classe peut admettre
plusieurs clés.
Un ensemble d’attributs K de C forme un identifiant
(ou clé) de C si :
·
tous les attributs de K
sont monovalués et avec des domaines dont aucun n’est de type texte;
·
deux objets o et o’ de C ne
peuvent prendre les mêmes valeurs pour K : o[K] ¹ o’[K] ;
·
K est minimal : il n’existe
aucun sous-ensemble de K vérifiant la propriété précédente.
Remarque: un identifiant K non
obligatoire ne permet pas d’identifier les objets qui prennent des valeurs
obscures pour K. De plus les objets peuvent changer de valeur pour K car les
attributs de K ne sont pas obligatoirement permanents.
Dans l’exemple GVA, NoChâssis,
NoVéhicule et NoMoteur sont trois identifiants distincts de la classe Véhicule.
Seuls NoChâssis et NoVéhicule sont des attributs permanents. Ainsi Véhicule
admet :
·
2 identifiants
obligatoires : NoChâssis ; NoVéhicule ;
·
1 autre identifiant qui n’est
pas obligatoire : NoMoteur.
Voici la notation proposée, où le séparateur
/ sépare les différents identifiants et le séparateur // sépare les
identifiants des attributs de la classe, qui n’appartiennent à aucun
identifiant.
VÉHICULE
(oidVéhicule / NoChâssis / NoVéhicule / NoMoteur // Catégorie, Marque,
DateCirculation).
Comment les SGBD
prennent-ils en compte les classes ?
Il s’agit ici de
présenter les connaissances du monde informatique indispensables et suffisantes
pour comprendre comment les classes sont gérées par les SGBD. Ces connaissances
vont grandement aider à comprendre le passage des spécifications de classes
faites dans le monde conceptuel aux implémentations faites dans le monde
informatique. Bien sûr le lecteur qui s’intéresse à comprendre de manière
approfondie les mécanismes de SGBD ne trouvera pas dans ce paragraphe
l’ensemble des connaissances de ce domaine strictement technique.
En informatique, la page
En informatique,
il y a la nécessité de découper les énormes espaces physiques de stockage de
données que sont les disques, en pages qui sont en fait des
compartiments de stockage. Une page représente une partie du disque qui peut
être lue (c’est-à-dire amenée en mémoire centrale) en une seule
opération d’entrée-sortie. Chaque page est elle-même divisée en enregistrements.
En fait, il existe de nombreuses manières de diviser un espace physique de
stockage en pages, chaque page en enregistrement. Plusieurs pages peuvent être
regroupées en zones.
Avant les SGBD,
chaque développeur d’applications devait prendre des décisions d’architecture
et assumer ensuite la programmation du stockage des données et de leur accès.
Autant dire qu’il valait mieux rester dans des architectures très simples comme
les fichiers séquentiels. Avec les SGBD ce sont les concepteurs de SGBD qui
fournissent les schémas informationnels des architectures les plus rusé, les
plus performantes pour le stockage et l’accès aux données et c’est au SGBD de
prendre en charge leur implémentation.
Face à toute une
infinité d’architectures informatiques possibles, il fallait retenir un premier
principe d’architecture qui semblait conduire à des possibilités
intéressantes : les enregistrements seraient divisés en champs,
chaque champ ayant une nature informatique précise (entier, flottant, chaîne de
caractères…), et l’ensemble de ces champs ayant une structure prédéfinie. De ce
premier principe découle une règle de conception de bdd :
(r1) une donnée ne
peut être stockée dans une bdd que si elle se réclame d’une structure connue.
Chaque structure est composée de champs. Ainsi, avant de pouvoir stocker une
donnée dans une bdd, il faut d’abord avoir défini l’ensemble des
structures des enregistrements de la base.
Face à la
multiplication des fichiers et des réplications des mêmes données en plusieurs
lieux, avec tous les problèmes d’incohérence, les architectes des SGBD se sont
pliés au principe : à une donnée un seul lieu informatique. Par
exemple une commande qui migrait de fichiers en fichiers pour se
transformer en facture et livraisons dans un traitement classique de
commandes, occupe un et un seul lieu dans une bdd : elle va alors passer
dans plusieurs états. De ce second principe découle une seconde règle de
conception de bdd :
(r2) une donnée
peut être prise en compte dans un SGBD seulement si sa structure tient compte
de tout son cycle de vie. Ainsi, avant de stocker une donnée dans une bdd,
faut-il d’abord décrire tout son cycle de vie.
Face au dédale
que représentent les différents codages informatiques des données et face aux
possibilités informatiques qui permettent d’avoir accès aux enregistrements de
manière performante, en connaissant leurs rangs ou leurs noms, les SGBD
prennent en charge eux-mêmes les procédures informatiques assurant ces accès.
Ce ne sont plus les développeurs de bdd qui en ont la tâche. Avec ce troisième
principe, toute personne voulant accéder à une donnée le fait en donnant le nom
de cette donnée. De ce troisième principe découle une troisième règle de
conception de bdd :
(r3) chaque
donnée stockée doit avoir un nom. Chaque SGBD a un modèle de données qui permet
l’accès à toute donnée stockée dans la base, au travers d’un nom. Construire
une bdd demande d’abord de fournir un schéma de la base dans les termes
du modèle de données supporté par le SGBD.
Première machine abstraite de SGBD
Ainsi une machine
abstraite de SGBD se compose de trois espaces, l’espace des noms, l’espace des
lieux et celui des valeurs (Cf. Chapitre Introduction aux SGBD).
Toutes les
entrées-sorties (E/S) d’une bdd se fait au travers de son espace des noms, que
ces E/S soient déclenchées par un développeur ou un utilisateur, par une
transaction ou une méthode. C’est à la charge du SGBD de transformer ce nom en
une adresse d’un lieu de stockage de la base : cette partie du SGBD est
appelée la gestion du catalogue. Ensuite c’est à la charge du SGBD de
remonter le contenu binaire du lieu déterminé et de le transformer dans des
termes compréhensibles que sont des entiers ou des réels ou des
caractères : cette partie du SGBD est appelée la gestion des domaines.
Page et classe
Nous avons vu que le niveau informationnel se compose des
concepts de classes,
d'attributs, de domaines alors que le monde informatique propose des pages, des
enregistrements et des champs pour stocker les informations. La page est la
quantité d’octets qui sont échangés lors d’une opération d’E/S, entre la
mémoire principale et la mémoire secondaire.
Cette section présente comment les SGBD peuvent faire correspondre les
concepts des deux mondes, ce qui revient à étudier comment stocker les
informations relatives à une classe.
En fait, il y a
deux grands types de stockage :
·
pour le premier, une page contient des objets d’une même classe ; dans
ce cas, il n’y a pas de choix !
·
pour le second, il y a la possibilité de stocker des objets de classes
différentes dans la même page ; l’intérêt ? Retrouver de manière plus
performante des objets de classes différentes, mais qui sont très souvent ensemble
dans les réponses. À ce moment, c’est au responsable informaticien de faire
preuve de savoir faire pour que la bdd soit la plus performante possible.
Stockage vertical
La correspondance
la plus simple entre les mondes informationnels et informatique se base sur le
principe suivant : à une classe va correspondre une seule zone, et
réciproquement. À un objet va correspondre un seul enregistrement, et
réciproquement. Ainsi une page va contenir des enregistrements qui sont
associés à des objets d’une seule classe, et toutes les pages d’une même zone
sont relatives à la même classe.
Une classe regroupe des objets qui ont une structure commune :
celle-ci va s’exprimer à l’aide des champs. À chaque champ est associé un
domaine de valeurs, qui indique au SGBD, comment il doit interpréter les
valeurs binaires d’un enregistrement pour un champ donné. On fait correspondre
la concept d’attribut au concept de champ du niveau informatique. Un attribut
est associé à un domaine informatique (entier, réel, caractères) et permet la
représentation des objets d’une classe dans une base. Chaque objet prend une
valeur par attribut : en fait, du point de vue informatique, c’est
l’enregistrement qui correspond à l’objet, qui va prendre une valeur binaire
pour le champ correspondant à l’attribut. Le domaine de l’attribut indique au
SGBD comment interpréter la valeur binaire du champ.
Monde informationnel |
Monde informatique |
Classe |
Zone mémoire |
Objet |
Enregistrement |
Attribut |
Champ |
L’ordre des attributs d’une classe n’a aucune importance au niveau du
schéma de la classe : par contre le SGBD va leur attribuer un ordre avec
lequel il retrouve les valeurs d’un objet pour un attribut donné.
Si l’attribut est
multivalué, alors la situation confortable pour les concepteurs de SGBD est de
supposer connue la cardinalité maximale de la multivaluation. Par exemple si
l’attribut DateCirculation de la classe VEHICULE est multivalué, il faut
fournir sa cardinalité maximale. Quand on ne la connaît pas vraiment, il faut
l’inventer, en voyant grand : dans le cas de DateCirculation, on va dire
10. Alors le SGBD va réserver pour chaque objet 10 places pour stocker des
dates de mise en circulation. Bien sûr, il y aura de la place perdue. Bien sûr
un jour ou l’autre, il y aura un objet pour qui il faudra une onzième date de
mise en circulation !
Bref, si le
stockage de la multivaluation avec une cardinalité maximale claire, trouve une
solution informatique simple et efficace, il en va autrement dans les autres
cas : le SGBD doit contenir des mécanismes qui gèrent cet espace de
stockage de manière dynamique : allouer de la place supplémentaire,
récupérer des places libres. Ces mécanismes sont bien maîtrisés du point de vue
technique. Mais si les SGBD ne les possèdent pas, alors il peut y avoir de
mauvaises surprises au moment de l’exploitation de la base et des performances
des transactions qui vont modifier les valeurs pour ces attributs.
Dans le passage
du monde informationnel au monde informatique il y a plusieurs raisons qui
peuvent conduire à décomposer une classe en plusieurs classes ayant des clés
équivalentes ou des mêmes clés :
·
des raisons liées aux performances ;
·
des raisons liées aux situations de concurrence et de confidentialité.
Prenons par
exemple la classe Chauffeur (NoAVS // NomCh, PrénomCh, AdresseCh,
DateNaissanceCh, SexeCh, TotalHCh), qui associe à un numéro AVS, un nom et
prénom du chauffeur, son adresse, sa date de naissance, son sexe et le total
d’heures effectuées depuis le début du mois.
Nous supposons
qu’une page fasse 1000 mots de 32 bits. Nous raisonnons en stockage vertical.
Les valeurs pour
NoAVS, DateNaissanceCh, SexeCh, TotalHCh occupe chacune 1 mot de 32 bits.
Les valeurs pour
NomCh, PrénomCh, AdresseCh occupent au total 96 mots. Ainsi un objet de
Chauffeur occupe 100 mots. Une page va donc contenir 10
objets de Chauffeur.
Par contre si on
décompose Chauffeur en deux classes :
Chauffeur-ADM
(NoAVS//Nom, Prénom, Adresse, DateNaissance, Sexe),
et Chauffeur-TRV(NoAVS // TotalH).
Alors
un objet de Chauffeur-TRV occupe 2 mots, et il y en a 500 par
page !
Tous
les traitements qui portent seulement sur NoAVS et TotalH vont voir leurs
performances nettement améliorées. De plus, ces traitements ne vont pas être
gênés par ceux qui veulent par exemple mettre à jour l’adresse d’un chauffeur,
à cause de problèmes de concurrence d’accès. En plus du point de vue de la
confidentialité, il semble bien qu’ici, cette décomposition corresponde à deux
responsabilités différentes : l’une administrative, l’autre relative aux
activités des chauffeurs.
Quand on
décompose, la situation la plus simple est alors de choisir l’une des classes
obtenues après décomposition comme pivot, par exemple dans le cas
précédent on prend Chauffeur-ADM. Alors un objet
d’une autre classe de la décomposition, par exemple Chauffeur-TRV, ne peut
exister qu’associé à un objet de la classe pivot. Ainsi si l’on souhaite
trouver tous les NoAVS stockés dans la base, il suffit d’interroger la classe
pivot Chauffeur-ADM.
Une fois les
données stockées, il faut y accéder dans un temps convenable. Dans ce dessein,
les concepteurs de SGBD ont mis au point d'une part des mécanismes de clés pour
retrouver les objets, d'autre part, des mécanismes comme les index pour
améliorer l'efficacité de l'accès.
Clé primaire
Les SGBD objets
prennent automatiquement en compte les identificateurs d’objets. Ils s’en
servent pour retrouver les objets dans l’espace informatique de stockage. C’est
une décision des responsables de conception de SGBD de savoir s’ils rendent ces
identificateurs d’objets disponibles aux développeurs ou non, aux personnes
interrogeant la base ou non. Dans les SGBD relationnels, ces identificateurs
d’objets existaient le plus souvent, mais étaient invisibles. Bien sûr le SGBD
garantit que deux objets ne peuvent pas avoir le même identificateur !
Le mécanisme de
clé, qui garantit que deux objets d’une classe ne peuvent avoir les mêmes
valeurs pour les attributs d’une clé, et qui permet de retrouver un objet à
partir des valeurs qu’il prend pour une clé, est un mécanisme facile à
implanter, bien connu et sans surprise technique.
Par contre, à
cause de contraintes techniques, une des clés sera nettement favorisée au
niveau des performances : cette clé est souvent appelée la clé primaire de
la classe (ou relation). Comme cette clé va servir à retrouver tous les objets
de la classe, elle doit être une clé obligatoire de la classe.
Il faut donc
choisir la clé primaire parmi les clés obligatoires de la classe. Les critères
de choix vont concerner les façons d’accéder aux objets de la classe. Dans
l’exemple de la classe Véhicule, le choix entre les deux clés obligatoires NoChâssis, NoVéhicule revient à se demander si les objets seront plus souvent atteints en
connaissant le numéro de châssis que le numéro de véhicule. Si l’on pense que c’est plutôt l’inverse, alors on va
choisir comme clé primaire NoVéhicule.
Potentiellement
les SGBD peuvent prendre en compte les autres clés sans aucun problème
difficile à résoudre. Maintenant c’est la liberté des responsables de marques
de SGBD de mettre à disposition de leurs clients ces mécanismes ou non.
Index
Un index sur une
classe permet de retrouver les objets de la classe qui prennent une certaine
valeur pour les attributs de l’index, de manière beaucoup plus efficace que le
simple parcours séquentiel. Il est construit à partir d’attributs de la classe.
Une classe peut être munie de plusieurs index.
Ainsi pour la
classe VÉHICULE (oidVéhicule / NoChâssis / NoVéhicule / NoMoteur // Catégorie,
Marque, DateCirculation), on peut construire un index sur l’attribut
DateCirculation si l’on s’aperçoit qu’il y a de nombreuses requêtes ou
traitements qui atteignent les objets de VÉHICULE en connaissant les valeurs
prises pour DateCirculation, du style : « trouver tous les
véhicules mis en circulation depuis le 1er septembre ».
La décision de
créer un index dépend des accès qui vont être le plus souvent effectués par les
requêtes les plus souvent posées et par des performances que doivent satisfaire
les traitements. Une telle décision demande des compétences informatiques.
Mais il faut
savoir que si les objets de la classe sont souvent mis à jour relativement aux
attributs de l’index, alors le SGBD devra en plus de faire la mise à jour des
objets, mettre à jour les index concernés : cette opération supplémentaire
va ralentir les performances du traitement qui l’a provoquée. Ainsi dans
l’exemple précédent, le changement de la date de mise en circulation d’un
véhicule, (du 1er mai, elle passe au 1er juin), demande aussi que ce véhicule
ne soit plus référencé par la valeur de l’index « 1er mai » mais
maintenant par celle de « 1er juin », ce qui constitue un travail
supplémentaire qui va pénaliser les performances du traitement qui met à jour
la date de mise en circulation.
Aussi, pour
construire des index, faut-il mieux utiliser des attributs permanents ou
relativement stables (c’est-à-dire, dont les valeurs sont peu souvent
modifiées). Généralement, les SGBD indexent automatiquement les attributs de la
clé primaire.
Enfin il est
possible de disposer de plusieurs index sur une classe, le SGBD choisissant
alors parmi l’index le plus approprié pour un traitement.
Dans le monde
relationnel, une classe est en forme normale si tous ses attributs sont
monovalués.
Avant les SGBD,
les responsables utilisaient dans les enregistrements de fichiers, des tableaux
à profusion. Par exemple, pour associer à une personne son salaire mensuel et
ses primes mensuelles, il suffisait de construire la structure suivante
d’enregistrement d’un fichier : PERSONNE(NoAVS//NOMPERS, (SALAIRE, PRIME)*), qui
pourrait être la définition d’une classe dans le monde objet.
Mais alors avec
une telle pratique, il est beaucoup plus difficile d’atteindre les données
simplement par leur nom indépendant de l’informatique. Dans l’exemple c’est le
concept de mois qui n’est pas explicité dans le schéma. Ainsi pour
trouver le salaire de la personne au mois de décembre faut-il savoir que
probablement ce mois correspond à la 12e position du tableau (SALAIRE,
PRIME)* ; même si une personne peut arriver à le deviner (en espérant
que, sans le savoir, elle ne se trompe pas !) le SGBD lui ne va pas y
arriver : Décembre restera un concept inconnu du SGBD. Aucun lien ne
pourra être fait entre un objet de Personne et un autre objet d’une autre
classe au travers des mois !
C’est pour cela
que le monde relationnel a introduit le concept de forme normale :
les classes (ou relations) doivent ne contenir que des attributs monovalués.
C’est un concept
phare du modèle relationnel. Il a amené une profonde rupture dans les habitudes
de déclaration de structure de données qui utilisaient à prolifération des
tableaux. Tous les SGBD relationnels ont été construits sur ce principe de
forme normale, obligeant ainsi tous les développeurs de bases à ne jamais
utiliser les tableaux dans la définition des attributs de classes. Ainsi toutes
les données pouvaient être atteintes par leur nom.
Dans le monde
objet, on a réintroduit
la possibilité des attributs multivalués et des groupes multivalués
d’attributs. Si l’on ne veut pas régresser aux structures des fichiers, il va
falloir permettre l’accès par nom même dans le cadre des multivaluations. Dans
ce dessein, on utilise des classes normales, des clés globales et des clés
partielles.
Ainsi la classe
précédente se transforme en : PERSONNE (NoAVS // NOMPERS, (MOIS //
SALAIRE, PRIME)*). MOIS est explicité, et l’on a écrit qu’à un mois
donné et à un numéro AVS donné, correspondent un seul salaire et une seule
prime. NoAVS est une clé globale de PERSONNE, (NoAVS,
MOIS) en est une clé partielle pour les attributs Salaire et
Prime.
Une classe est normale
si tous ses attributs sont déterminés par une clé globale ou partielle.
Si une classe est
normale, alors le SGBD garantit l’accès aux données par les noms qu’elles
prennent pour des attributs, sans qu’aucune personne n’ait à se soucier ni
d’indices de tableaux ni d’identificateurs d’objets.
Prenons un autre
exemple, celui de voyages qui s’effectuent au travers de plusieurs pays.
Une modélisation
en forme normale traditionnelle donne :
Voyage (NoVoyage
// PrixVoyage)
Voyage-Pays
(NoVoyage, Pays // Nbjours).
Une modélisation
en classe normale peut aussi donner :
Voyage (NoVoyage
// PrixVoyage, (Pays // Nbjours)*).
Nous verrons dans
le chapitre suivant comment comparer ces deux modélisations.
Les SGBD permettent de modifier les objets des classes avec des opérations
de création, de suppression et de modification des objets de la classe. Mais au
niveau informationnel il est très important de travailler avec ces mêmes
opérations pour bien comprendre et bien spécifier la bdd et ses traitements
ensuite. De plus ce ne sont pas seulement les opérations sur les objets qui
sont intéressantes au niveau informationnel, mais aussi les opérations sur les
classes car dans un processus de modélisation, de conception et de
spécification, l ne cesse de bouger les résultats intermédiaires.
Nous allons
considérer les opérations essentiellement au niveau informationnel. Comme
certaines d’entre elles sont très voisines de celles du niveau informatique
nous ferons les liens qui nous ont paru s’imposer.
Nous allons présenter les opérations pour
·
déclarer une classe et la modifier,
·
manipuler les objets des classes,
·
préciser la confidentialité des objets et des classes.
Noms de classes et de domaines
Une classe doit
avoir un nom qui la distingue de toutes les autres classes.
Il vaut mieux que
les domaines et les classes aient des noms distincts, car il est tout à fait
possible qu’au cours d’une modélisation, un domaine devienne une classe. Ainsi
est-il bien difficile de savoir si le concept de Pays doit être représenté par
un domaine ou une classe. On peut commencer par le prendre pour un domaine et
s’apercevoir ensuite qu’il faut lui accrocher des attributs, comme sa
superficie, son nombre d’habitants…
Aussi, au niveau
informationnel, notre conseil est-il simple : utiliser les domaines
seulement quand vous êtes sûr que jamais vous n’aurez jamais besoin de le
transformer en classe !
Au plan
informatique, nous recommandons aussi une grande prudence. Par exemple, si Pays
est un simple domaine avec une liste de valeurs, dès qu’un nouveau pays doit
être pris en compte, il faut modifier cette liste de valeurs. Mais cette
opération est une opération de restructuration du schéma, qui est une opération
compliquée : en effet généralement seuls les administrateurs de la bdd ont
l’autorisation de modifier le schéma d’une bdd.
Par contre si
Pays était une classe, il suffirait de rajouter un nouvel objet !
De même si l’on
faut prendre en compte des attributs d’un pays, comme son nombre d’habitants,
alors il n’y a qu’une solution : que Pays soit une classe ! mieux
vaut l’avoir fait dès le départ pour avoir moins de regrets ensuite !
Prédicat d’une classe
Ce prédicat doit
être décrit en langue naturelle à l’aide des attributs de la classe avec
beaucoup de soin. Il doit indiquer notamment quand un n-uplet formé sur les
domaines des attributs peut être considéré comme un objet de la classe et quand
il ne doit plus l’être. Ce prédicat est comme une explication des
concepteurs de la classe à toutes les personnes qui vont travailler sur cette classe
et sur ses objets.
Attributs
Les attributs
doivent avoir des noms qui permettent de les distinguer entre eux. Nous
conseillons fortement que :
·
les attributs de classes différentes aient aussi des noms distincts entre
eux,
·
si deux classes ont des attributs de même nom, c’est que justement ces
attributs forment des clés de classes.
À chaque
attribut, on associe son domaine et ses propriétés : admet-il les valeurs
obscures, est-il permanent, est-il monovalué ou multivalué ?
Domaine
Chaque domaine
doit avoir un nom qui le distingue des autres domaines et des classes. Il faut
lui associer son type et la liste des valeurs qui lui sont autorisées.
Identifiant ou clé
On indique la
liste des attributs de chaque identifiant. Bien sûr il faut vérifier que ces attributs
sont monovalués et qu’aucun de leurs domaines n’est de type texte.
Il faut préciser
si l’identifiant est obligatoire ou non. S’il l’est, il faut vérifier en plus,
que tous ses attributs n’admettent aucune valeur obscure et sont permanents.
Méthodes
À chaque méthode, on associe un nom qui va la
distinguer de toutes les autres méthodes de la classe. Notre conseil est que ce
nom la distingue de toutes les méthodes définies aussi sur les autres classes
mais aussi de tous les attributs et classes. Pour chaque méthode, il faut
indiquer si elle risque de créer de nouveaux objets, de supprimer des objets,
de modifier des objets existants et si oui, par rapport à quels attributs ou
d’interroger des objets. À ce moment aussi il faut un prédicat qui décrive en
langue naturelle le fonctionnement de cette méthode et ses objectifs.
Il existe
plusieurs langages mis à la disposition des personnes qui travaillent sur des
bdd en fonction de leurs rôles sur la base. Le langage de déclaration permet de
déclarer le schéma de la bdd. Le langage d’interrogation permet de poser et
d’écrire des requêtes à la bdd. Le langage de manipulation permet de modifier
la bdd en créant, supprimant ou mettant à jour des objets de la base. Le
langage de confidentialité permet de restreindre l’accès à des objets aux
seules personnes ayant les autorisations suffisantes. Enfin le langage
d’évolution de la base permet de modifier le schéma de la base.
Les langages de
déclaration, d’évolution et de confidentialité se ressemblent syntaxiquement,
ainsi que les langages d’interrogation et de manipulation entre eux.
Dans ce chapitre,
nous ne présentons que les parties de ces langages concernant seulement une
classe. Cette présentation est rapide, s’appuie sur la norme SQL [Date 97],
demande de consulter des ouvrages spécialisés pour approfondir toutes les
subtilités et surtout faire des exercices.
Du point de vue
terminologique, les classes ou relations sont souvent appelées tables
dans la littérature des SGBD, les attributs colonnes, les objets/entités
lignes.
Le langage de
déclaration permet de créer le schéma d’une classe / relation
Le schéma d’une
classe contient les attributs/colonnes, les vues, les index, construits sur
cette classe/table.
Création
simple d’une table
Voici la primitive de la création simple d’une
table et un exemple : create table R (att1 type1, att2
type2... attn typen) où att1, att2,..,
attn sont des attributs, type1, type2,.., typen,
des types de données.
Exemple: create
table Chauffeur (
NoAVS
char(12),
Nom
char(24),
Prénom
char(24),
DateNaissance
date,
Adresse
char(80),
Sexe
char(1),
TotalHeures
number)
pour créer la
table Chauffeur de l’exemple GVA.
Création d’une table avec insertion de
données
Voici la
primitive de la création d’une table avec insertion de données et un exemple :
create
table R (att1 type1, att2 type2...
attn typen)
as
select *
from S where P;
Exemple: create
table Chauffeur as select * from Chauffeur_Ancien pour d’une part créer la
table Chauffeur avec toutes les colonnes de Chauffeur_Ancien et d’autre part la
remplir avec les objets de la table Chauffeur_Ancien (ici il n’y a pas de
sélection).
Déclaration d’une vue
Une vue définie sur une classe permet de définir un sous-ensemble d’objets de cette
classe. Cette vue sert alors autant à
l’interrogation et manipulation de la bdd qu’à l’écriture de traitements. Elle
permet d'assurer une certaine indépendance logique
Voici la
primitive de la création d’une vue et un exemple :
create view R
on [(att1, att2,
…,attn)]
as
select
* from S where P
with
check option.
Exemple : create view Chauffeur_Féminin
as
select
* from Chauffeur
where Sexe = ‘F’
pour créer la vue
de nom Chauffeur_Féminin qui fait référence à des objets de Chauffeur vérifiant
le fait que ces objets prennent la valeur « F » pour l’attribut
Sexe.
Déclaration d’un index
Un
index contient une liste triée des valeurs des colonnes indexées, avec les
adresses des lignes correspondantes. Il a pour but d’accélérer la recherche
d'une ligne : à partir d'une valeur donnée d’une clé ou à partir d’une
valeur d'index supérieure ou inférieure à une valeur donnée.
Voici
la primitive de la création d’un index et un exemple :
create [unique] index Ri on R (att1, att2,
…,attn).
Exemple :
create index Ch_DateNaissance on Chauffeur (DateNaissance) pour créer un index
de nom Ch_DateNaissance sur la table Chauffeur à partir de l’attribut
DateNaissance;
Les mécanismes
fondamentaux sous-jacents aux interrogations d’une classe/relation/table sont
la projection, la sélection, les opérations ensemblistes.
Projection
La projection
d’un objet o d’une classe C sur un sous-ensemble A d’attributs Ai de
C est un objet op formé des seules valeurs prises par o pour les attributs Ai.
On note op = o[A] (notation relationnelle).
La projection
d’une classe C sur un sous-ensemble de ses attributs est une nouvelle classe CP
dont les objets sont des projections des objets de C. On note CP = C[A] (notation
relationnelle).
Voici la
primitive pour former une projection et un exemple : select A from C.
Exemple GVA pour
la classe Chauffeur : quels sont les noms des chauffeurs?
En notation
relationnelle : Chauffeur[Nom] ;
Avec la primitive
:
Select Nom from
Chauffeur ou
Select distinct
Nom from Chauffeur pour éviter les doublons (plusieurs fois le même nom dans
la réponse).
Sélection
La sélection
d’une classe/relation est une restriction de la classe/relation à un
sous-ensemble de n-uplets suivant un prédicat P.
Notation
relationnelle : C[P] = {o Î R et P(o)=vrai}.
Voici la
primitive pour former une projection et un exemple : select * from R where P.
Exemple : quels
sont les chauffeurs de sexe féminin?
Notation
relationnelle : Chauffeur [Sexe= `féminin´].
Avec la primitive
:
Select *
From Chauffeur
Where Sexe =
`féminin´ ;
Valeur obscure
La clause Null
permet de tester si une valeur est obscure ou non.
Par exemple :
quels sont les chauffeurs dont on ne connaît pas l’adresse?
Select
Nom, Prénom
From
Chauffeur
where
Adresse is null
Autre
exemple : quels sont les chauffeurs dont on connaît l’adresse?
Select
Nom, Prénom
From
Chauffeur
where
Adresse is not null
Opérations ensemblistes
-
Union
Faire l’union de
deux tables R et S, c’est constituer
l’ensemble des n-uplets qui appartient à l’une des deux tables
R È S = {n ÎR ou nÎS} ; ceci suppose pour éviter des
complications inextricables que les ensembles des attributs soient identiques
ainsi que les domaines des attributs deux à deux.
Notation
relationnelle RS = R È S.
Voici la
primitive pour former une union et un exemple : select CR from R Union select
CS from S.
Exemple :
pour trouver les chauffeurs identifiés par leur numéro AVS qui ont travaillé le
25 ou le 31 décembre 99, on écrit en relationnel : Aff-Chauffeur[DateAff =
25-12-99] [NoAVS] · Aff-Chauffeur[DateAff = 31-12-99] [NoAVS] et avec la
primitive :
select
NoAVS from Aff-Chauffeur
where
DateAff = 25-12-99
union
select NoAVS from Aff-Chauffeur
where DateAff =
31-12-99.
-
Différence
Faire la
différence entre deux tables R et S, c’est constituer l’ensemble des n-uplets
qui appartiennent à R et qui n’appartiennent pas à S; ceci suppose pour éviter
des complications inextricables que les ensembles des attributs soient
identiques ainsi que les domaines des attributs deux à deux.
Notation
relationnelle : R - S = {n ÎR et nÏS}
Voici la
primitive pour former une différence: select CR from R minus select CS from
S ;
Exemple : pour
trouver les chauffeurs identifiés par leur numéro AVS qui ne travaillent pas le
31 décembre 2000, on écrit en relationnel : Chauffeur[NoAVS] - Aff-Chauffeur
[DateAff = 31-12-00] [NoAVS], et avec la primitive :
Select
NoAVS from Chauffeur
Minus
Select NoAVS from AFF-Chauffeur
Where
DateAff = 31-12-00.
-
Intersection
Faire
l’intersection de deux tables R et S, c’est constituer l’ensemble des n-uplets
qui appartiennent à R et S :
R Ç S = {n ÎR et nÎS} ; ceci suppose pour éviter des
complications inextricables que les ensembles des attributs soient identiques
ainsi que les domaines des attributs deux à deux.
Notation
relationnelle RS = R Ç S.
Voici la
primitive pour former une intersection : select CR from R intersect select CS
from S.
Exemple : pour
trouver les chauffeurs identifiés par leur numéro AVS qui ont travaillé le 25
et le 31 décembre 99, on écrit en relationnel : Aff-Chauffeur[DateAff =
25-12-99] [NoAVS] · Aff-Chauffeur[DateAff = 31-12-99] [NoAVS], et avec la
primitive :
Select
NoAVS from AFF-Chauffeur
Where
DateAff = 25-12-99
Intersect
Select NoAVS from AFF-Chauffeur
Where DateAff =
31-12-99.
-
Calcul ensembliste sur des n-uplets
Il s’agit sur un
ensemble d’objets de faire des calculs à l’aide des fonctions ensemblistes
classiques : sum (somme des éléments), min (élément minimum), max (élément
maximum), count (nombre des éléments), avg (moyenne des éléments) à partir des
ensembles construits à partir des clauses select.
Exemple : pour
trouver le nombre de chauffeurs, on écrit :
Select
count(NoAVS) from Chauffeur.
Il s’agit
maintenant de faire des calculs sur des sous-ensembles : dans ce dessein,
on utilise la clause group by.
Exemple:
trouver le nombre d’heures moyen
effectuées par un chauffeur :
select NoAVS ,
avg(NbHeures)
from
Heure-Chauffeur
group by NoAVS.
Cette clause
group by regroupe les objets de Heure-Chauffeur qui ont le même numéro AVS
(NoAVS) ; pour chacun de ces sous-ensembles ainsi construits, le système
va calculer la moyenne de NbHeures.
Il s’agit
maintenant de filtrer au préalable les objets qui vont être concernés par la
clause group by.
Exemple : trouver
la moyenne des heures effectuées par les chauffeurs qui ont conduit un jour
plus de 10h :
select NoAVS ,
avg(NbHeures)
from
Heure-Chauffeur
group by
NoAVS
having
max(NbHeures)>10;
Insertion
Il s’agit
d’insérer un n-uplet dans une table en indiquant ses valeurs pour les
différents attributs de la table ou bien il s’agit d’insérer un ensemble de
n-uplets.
Notation
relationnelle : o :Î C.
Voici les
primitives pour une insertion :
insert into C
values (val1, val2, …, valn) pour insérer un
objet avec ses valeurs pour les attributs de C;
insert into C
(att1, att2, …,attn) values (val1,
val2, …, valn) pour insérer un objet prenant des valeurs
seulement pour certains des attributs de C;
insert into R
select * from S where P pour insérer des objets extraits d’une autre table et
vérifiant le prédicat P ;
où att1,
att2, …,attn désignent des attributs, val1,
val2, …, valn des valeurs à insérer, P un
prédicat.
Exemple :
Insert into
Chauffeur (AVS, Nom, Prénom, Adresse, DateNaissance, Sexe, TotalHeures) values
(‘0123456’, ‘LE’, ‘Boubou’, ’24 Général Dufour’, ’31-01-
Modification
Il s’agit de
modifier les valeurs prises par un ou plusieurs objets d'une classe pour un ou
plusieurs attributs.
Notation
relationnelle : (o ® o ’) :Î C.
Voici les
primitives pour une modification :
update C
set att1 = exp1, att2
= exp2,…, attn = expn
where P, pour que les objets de C vérifiant le prédicat P aient leurs
valeurs prises pour les attributs modifiés atti selon l’expression
expi ;
où exp1,
exp2,…,expn désignent des expressions, P, P1, P2 des
prédicats.
Exemple :
update Chauffeur
set TotalHeures =
20
where NoAVS =
‘0123456’ pour donner au chauffeur BouBou (qui a le numéro AVS égal ‘0123456’)
un total d’heures égal à 20.
Suppression
Il s’agit de supprimer un objet de C ou un
ensemble de ses objets.
Notation
relationnelle: o :Ï C.
Voici les
primitives pour une suppression :
delete from R
where P pour supprimer tous les objets de C vérifiant le prédicat P ;
Exemple : delete
from Chauffeur where NOAVS = ‘0123456’ pour supprimer l’objet qui a comme
numéro AVS ‘0123456’ et qui représente le chauffeur BouBou.
Les bdd
contiennent des données qui intéressent de nombreuses personnes qui assument
des tâches ou des responsabilités fort différentes. A priori toutes ces
personnes pourraient avoir accès à toutes ces données et les mettre à jour comme elles l’entendraient.
Comme ces données sont très souvent des données opérationnelles, il paraît
difficile d’organiser une institution sur un tel principe. Il semble
souhaitable de restreindre l’accès aux données et à leurs modifications à
certaines personnes en fonction de leurs responsabilités, tâches ou activités.
Dans d’autres cas, il semble même indispensable de protéger l’accès à des
données qui sont confidentielles, voire soumises au secret.
Les SGBD
permettent de définir des utilisateurs avec leurs rôles et leurs privilèges
Utilisateur
Un utilisateur d’une bdd a un mot de passe et
doit avoir le droit de connexion à la base pour interroger ou modifier ses
objets. Pour le SGBD, un utilisateur d’une bdd est un nom de compte qui permet
d'entrer dans la bdd.
Voici la liste
des primitives relatives à un utilisateur avec l’expression en SQL et un
exemple :
-
créer un utilisateur ;
CREATE USER
utilisateur IDENTIFIED BY mot de passe
[DEFAULT
TABLESPACE tablespace]
[QUOTA {entier
[K|M] | UNLIMITED} ON tablespace] ;
- exemple:
CREATE USER
le
IDENTIFIED
BY than
DEFAULT
TABLESPACE system
QUOTA
UNLIMITED ON system ;
-
modifier le mot de passe d’un utilisateur ;
ALTER USER
utilisateur
IDENTIFIED BY mot
de passe ;
- exemple de
changement du mot de passe de than en thang :
ALTER USER
le
IDENTIFIED
BY thang ;
-
accorder le droit de connexion à un utilisateur ;
GRANT CONNECT TO
utilisateur;
- exemple:
GRANT CONNECT TO
le ;
-
retirer le droit de connexion à un utilisateur ;
REVOKE CONNECT
FROM utilisateur;
- exemple:
REVOKE CONNECT
FROM le ;
-
supprimer un utilisateur ;
DROP USER
utilisateur;
- exemple:
DROP USER le ;
Rôle
Un rôle est un
privilège ou un ensemble de privilèges qui permettent à un utilisateur
d'exécuter certaines fonctions dans la bdd.
Les SGBD
proposent des primitives pour gérer ces rôles ; les personnes qui les
déclenchent, doivent avoir les privilèges adéquats.
Voici la liste
des primitives relatives à un rôle avec l’expression en SQL et un exemple :
-
créer un rôle :
CREATE ROLE rôle
NOT IDENTIFIED _
IDENTIFIED BY mot de passe ;
- exemple:
CREATE ROLE
développeur Not IDENTIFIED;
-
modifier un rôle :
ALTER ROLE
utilisateur
NOT IDENTIFIED _
IDENTIFIED BY mot de passe ;
- exemple:
ALTER ROLE
développeur
IDENTIFIED BY
secret ;
-
accorder un rôle à un utilisateur :
GRANT rôle TO
utilisateur;
- exemple:
GRANT développeur
TO le ;
-
retirer un rôle à un utilisateur :
REVOKE rôle FROM
utilisateur;
- exemple:
REVOKE
développeur FROM le ;
-
supprimer un rôle :
DROP ROLE rôle
[CASCADE];
- exemple:
supprimer le rôle développeur et ses utilisateurs
DROP ROLE
développeur CASCADE ;
Privilèges
Les privilèges sont des permissions que les
utilisateurs auront sur la bdd. Il y a deux types de privilèges qui peuvent
être accordés aux utilisateurs: des privilèges de système, des privilèges
d'objet.
Les privilèges de
système concernent par exemple des modifications du schéma de la base pour
assurer l’évolution de la bdd (comme pour exécuter les primitives CREATE ANY
TABLE, ALTER ANY TABLE, DELETE ANY TABLE, SELECT ANY TABLE, UPDATE ANY ROWS.
Voici les
primitives attachées aux privilèges de système :
-
accorder un privilège de système à un utilisateur ou un rôle :
GRANT privilège
de système TO {utilisateur | rôle} ;
exemple :
GRANT SELECT ANY
TABLE TO développeur;
-
retirer un privilège de système d’un utilisateur ou un rôle :
REVOKE privilège
de système FROM {utilisateur | rôle} ;
exemple :
REVOKE
SELECT ANY TABLE FROM développeur;
Les privilèges d’objet
concernent les modifications d’objets et les requêtes sur les objets.
Voici les
primitives attachées aux privilèges d’objet :
-
accorder un privilège d’objet à un utilisateur ou un rôle :
GRANT privilège
d’objet TO {utilisateur | rôle} ;
exemple :
GRANT SELECT ON
Chauffeur TO développeur;
-
retirer un privilège d’objet d’un utilisateur ou un rôle :
REVOKE privilège d’objet FROM
{utilisateur | rôle} ;
exemple :
REVOKE SELECT ON Chauffeur FROM
développeur.
Ce langage
d’évolution se confond souvent avec les autres langages car du point de vue de la syntaxe
informatique il n’apporte aucune nouveauté : ainsi modifier une table ou créer une table,
accorder des privilèges ou supprimer des privilèges sont apparemment de la même
complexité informatique.
En fait c’est du
point des responsabilités humaines qu’il en va différemment. Par exemple on
peut vouloir modifier la colonne d’une table car au moment de la création, l a
fait une erreur (de recopie, de saisie…) ; mais on peut vouloir
déclencher la même primitive pour augmenter le domaine de la bdd ou pour
améliorer les services qu’elle rend : alors là il s’agit d’une autre
complexité, même si on va utiliser la
même primitive. Il s’agit alors de faire évoluer le schéma de la base,
s’assurer de la conformité des interfaces, des traitements, des droits d’accès,
des validations des règles d’intégrité (prochain chapitre), de
l’organisation autour de la bdd.
Après les
primitives d’évolution de la confidentialité, nous présentons celles qui
concernent les tables, les vues et les index.
Ajouter des colonnes à une table
Voici
l’expression de la primitive : alter table R add (att1 type1,
att2 type2… attn typen) où att1,att2,..,
attn sont des attributs, type1, type2,.., typen,
des types de données.
Exemple :
alter table Chauffeur add(Annotation char(80)) rajoute la colonne Annotation à
la table Chauffeur, le type informatique des valeurs de l’attribut Annotation
étant une chaîne de 80 caractères.
Modifier une colonne d’une table
La primitive
« modifier la définition d’une colonne » s’applique autant dans le
cas d’une bdd vide que dans celui d’une bdd contenant déjà des objets de cette
table. Si l’on veut éviter des cas compliqués, cette primitive ne peut être
déclenchée que si les conditions suivantes sont vérifiées :
·
si l’on veut diminuer la taille informatique des valeurs ou changer le type
d’une colonne, alors la colonne doit être actuellement vide (ne contient aucune
valeur dans la bdd) ;
·
si l’on veut spécifier que la colonne devient obligatoire (Not Null), alors
la colonne ne contient actuellement aucune valeur Null dans la bdd.
Voici
l’expression de la primitive : alter table R add (att1 type1,
att2 type2… attn typen) où att1,att2,..,
attn sont des attributs, type1, type2,.., typen,
des types de données.
Exemple :
alter table Chauffeur add(Annotation char(180)) pour augmenter la taille de la
colonne Annotation de 80 caractères à 180 caractères.
Supprimer une table
Voici
l’expression de la primitive : drop table R.
Exemple :
drop table Chauffeur, pour la suppression de la table Chauffeur.
Renommer une table
Voici
l’expression de la primitive : rename R to S.
Exemple :
rename Chauffeur to Chauffeur_Ancien pour renommer la table Chauffeur en
Chauffeur_Ancien.
Supprimer une vue
Voici
l’expression de la primitive : drop view R.
Exemple :
drop view Chauffeur_Féminin pour supprimer la vue Chauffeur_féminin.
Renommer une vue
Voici
l’expression de la primitive : rename R to S.
Exemple :
rename Chauffeur_Féminin to Woman_Driver pour renommer la vue Chauffeur_féminin
en Woman_driver.
Supprimer un index
Voici
l’expression de la primitive : drop index Ri.
Exemple :
drop index Ch_DateNaissance pour supprimer l’index qui a pour nom Ch_Datenaissance.
Renommer un index
Voici
l’expression de la primitive : rename Ri to Rk.
Exemple :
rename Ch_DateNaissance to Driver_Birthday pour renommer l’index
Ch_Datenaissance en Driver_Birthday.
Comprendre les
enjeux des associations entre classes demande de considérer le domaine des
systèmes d’information comme le domaine qui coordonne les activités des trois
mondes : le monde vivant des organisations, le monde informatique et le
monde communicationnel. Considérer les associations entre classes du point de
vue d’un seul de ces mondes conduit à réduire la complexité des associations
dans le monde des systèmes d’information et donc à acquérir une connaissance
superficielle.
Dans le monde
artificiel informatique, les associations entre classes correspondent en fait à
des chemins d’accès entre objets,
c’est-à-dire des possibilités techniques de relier un objet à un autre objet.
Depuis que l’informatique existe, il y a toujours eu ce genre de mécanisme qui
permet de passer d’un endroit à un autre : par exemple, en programmation,
les expressions conditionnelles et les expressions de déroutement, en gestion
de mémoires, des listes qui chaînent entre eux différents objets…
Ainsi on pourrait
imaginer que tout objet de toute classe puisse être associé à n’importe quel
objet de n’importe quelle autre classe. En fait les architectes des bases de
données ont restreint cette possibilité en respectant ce principe: si un objet d’une classe C est associé à un
objet de la classe C’, alors tout objet de C peut être associé à un objet de C’.
Leur point de vue peut se comparer à celui des architectes de la programmation
structurée, qui n’ont pas retenu dans leurs langages la fameuse instruction de
déroutement Aller-à (GoTo) :
·
pourtant elle permettait à un programmeur de se sortir d’embarras quand il
était aux prises avec une situation non prévue lors de la conception,
·
mais, en contre partie, elle rendait alors le programme très difficilement
compréhensible, vérifiable et communicable. Souvent l’utilisation de cette
instruction était le signe du manque de maîtrise de la difficulté rencontrée
dans la conception et programmation.
Vu le grand
nombre d’objets d’une base de données, on peut facilement accepter la
pertinence de ce principe pour développer des SI ; ainsi on tente d’éviter
des bases de données où les objets sont reliés entre eux de manière
inintelligible. Dans les bases de données, c’est au niveau des classes que sont
définis les chemins d’accès : si la classe Véhicule est associée à la
classe Personne, alors tout objet de Véhicule peut être associé à un objet p de Personne par un chemin d’accès qui
est par exemple un pointeur contenant l’adresse de p. Ainsi un SGBD permet de naviguer
d’objets en objets en passant de classes en classes et en suivant les chemins
d’accès.
Dans le monde
vivant, en simplifiant, si les classes représentent des concepts, alors les
associations entre classes représentent des phrases formées sur ces concepts.
Ainsi entre les classes Personne et Véhicule on peut faire les phrases
suivantes : une personne est propriétaire d’un véhicule, ou bien une personne
conduit un véhicule, ou bien une personne répare un véhicule… Réciproquement,
de toute phrase, on peut extraire des concepts et donc des classes, et des
associations entre des classes. Ainsi à la phrase suivante : tel chauffeur conduit tel véhicule pour
effectuer tel trajet, correspondent les concepts de Chauffeur, Véhicule,
Trajet et une association Conduire pour
effectuer construite sur ces classes. De plus une phrase peut se diviser en
plusieurs propositions comme des propositions principales et relatives : tel chauffeur conduit tel véhicule, qui est
assuré auprès de telle compagnie d’assurances, pour effectuer tel trajet. A
une telle phrase correspondent deux associations, la première Conduire pour effectuer formée sur les
classes Chauffeur, Véhicule et Trajet, et la seconde Etre
assuré formée sur les classes Véhicule
et Compagnie-d’assurances. En
fait cette même phrase peut s’analyser autrement à l’aide de la proposition
infinitive, et faire apparaître trois associations :
·
une première proposition : tel
chauffeur conduit tel véhicule, à laquelle correspond l’association Conduire formée sur les classes Chauffeur et Véhicule ;
·
une seconde : tel véhicule, qui
est assuré auprès de telle compagnie d’assurances, à laquelle correspond
l’association précédente Etre
assuré ;
·
une troisième : pour effectuer
tel trajet, à laquelle correspond l’association Effectuer formée sur Conduire
et Trajet.
Dans les SI, les
associations jouent un rôle intrinsèque fondamental car les informations ne
sont pertinentes que si elles sont en association avec d’autres informations.
Dans le monde
informationnel des SI, les associations prennent la forme de fonctions ou
d’applications définies entre ensembles. Ainsi si un véhicule est assuré par
une compagnie d’assurances, on va considérer qu’il existe une application Etre assuré de l’ensemble de Véhicule dans l’ensemble de Compagnie-d’assurances, au sens de la
théorie des ensembles et comme le font des méthodes formelles comme Z ou B
[Lano 96] (on note c = Etre assuré(v)) :
·
cette application est une fonction
si un véhicule est assuré par au plus une compagnie ;
·
elle est partout définie si tout
véhicule est assuré par au moins une compagnie ;
·
elle est injective si deux véhicules
ne peuvent pas être assurés par une même compagnie ;
·
elle est surjective si toute
compagnie assure au moins un véhicule.
Dans le cas de
l’application Etre assuré, cette
application est une fonction partout définie, surjective et non-injective.
Dès que l’on
définit une application, on lui associe son application réciproque : dans
le cas de l’application Etre assuré,
c’est l’application Assure qui est
une application de Compagnie-d’assurances
dans Véhicule. Bien sûr, si c = Etre assuré(v), alors la compagnie c assure v : v Î Assure(c). A cause des propriétés de la fonction Etre assuré, on sait que l’application Assure n’est pas une fonction, qu’elle
est partout définie, surjective et injective.
De la même façon,
on considère l’application Conduit de
l’ensemble Chauffeur dans l’ensemble Véhicule : si ch est un élément de Chauffeur,
alors Conduit(ch) désigne l’ensemble
des véhicules que conduit le chauffeur ch.
Il est possible de faire la composition d’applications : par exemple Etre assuré o Conduit(ch) fournit l’ensemble des compagnies d’assurances
assurant les véhicules que ch
conduit.
Pour éviter la
redondance entre une application et son application réciproque, on peut
considérer une relation Assurance
entre Véhicule et Compagnie-d’assurance, telle que si un
véhicule v et une compagnie c sont associés dans la relation Assurance (on note (v, c) Assurance), alors cela signifie que v est assuré par c et que c assure v. Dans le cadre de ce modèle
relationnel, la composition d’applications va alors s’exprimer à l’aide de la composition de relations.
Pour les trois
mondes précédents, le concept d’association est un concept central. Pour le
monde des SI, ce ne sont pas simplement ces mondes pris isolément qui sont
importants, mais c’est aussi leur coordination pour permettre des
développements efficaces de SI pertinents. Et c’est dans cette coordination que
se trouvent les enjeux des associations dans les SI. Il ne s’agit plus de
développer le concept d’association dans un des mondes sans se préoccuper des
autres mondes.
Monde vivant – Monde informationnel
Dans l’espace du
monde vivant, il est évident qu’il existe une infinité de phrases et que toutes
ne donnent pas lieu à des représentations dans le SI. Il s’agit d’avoir des
critères de choix pour ne retenir que les seules phrases importantes pour le
SI. A l’aide de l’exemple précédent on a constaté que :
·
les phrases peuvent mettre en jeu plusieurs classes : les associations
ne sont pas simplement binaires, mais n-aires;
·
les formulations des phrases peuvent être mises sous la forme active (cette compagnie assure ce véhicule) ou
passive (ce véhicule est assuré par cette
compagnie) : le modèle informationnel ne privilégie ni l’une ou ni
l’autre forme ;
·
il est possible de construire des associations sur des associations
(association Effectuer formée sur Conduire et Trajet).
Monde
informationnel – Monde artificiel
Les seuls mécanismes simples d’association connus
dans le monde informatique des SGBD sont de nature binaire : ils
permettent d’associer un objet d’une classe à un ou plusieurs objets d’une
autre classe. Seules deux classes sont concernées par un mécanisme
d’association au niveau informatique, alors qu’au niveau du monde
informationnel les associations peuvent ne pas être binaires.
D’autre part,
d’un côté il y a la composition des associations et de l’autre, le mécanisme de
navigation : il faut assurer la compatibilité de ces deux niveaux pour que
les raisonnements faits autant au niveau du monde vivant qu’au niveau
informationnel puissent avoir une représentation fidèle au niveau informatique.
Voici la
prolongation de l’exemple du chapitre précédent.
En italiques, se
trouvent des attributs communs à plusieurs classes et qui vont servir à faire
des associations entre des objets.
CHAUFFEUR
(Nom Prénom / NoAVS // Adresse DateNaissance
Sexe TotalHeures)
PERMIS
(NoAVS Catégorie // DatePermis)
VEHICULE
(NoVéhicule // Catégorie Marque NoChâssis
NoMoteur DateCirculation)
LIGNE
(CodeLigne // Catégorie TypeLigne
ArrêtDépart ArrêtArrivée)
AFF-VEHICULE
(NoVéhicule DateAff //
StatutVéhicule CodeLigne StatutAffectation)
AFF-CHAUFFEUR
(NoAVS DateAff //
StatutChauffeur NoSérie)
TRANCHE-SERIE
(NoSérie CodeLigne // HeureDébut HeureFin)
HEURE-CHAUFFEUR
(NoVéhicule DateAff
NoAVS // Nb-Heures)
Voilà l’enjeu de
ce chapitre : présenter ces points de vue différents relatifs aux
associations et les concilier pour la réalisation efficace de SI pertinents.
Dans le monde
informatique des bases de données, c’est au niveau des classes que l’on indique
si leurs objets sont reliés à des objets d’autres classes ou non. S’ils sont
reliés entre eux, c’est par un mécanisme informatique que nous appelons
« chemin d’accès ».
Le but de ce
paragraphe est de présenter les bases de l’implémentation des chemins d’accès
dans les systèmes de gestion de bases de données (SGBD), qui comprennent :
·
les différentes techniques de désignation des objets,
·
la prise en compte des chemins d’accès inverses,
·
les différentes techniques d’implémentation des chemins d’accès monovalués
et multivalués,
·
les mécanismes de base liés aux contraintes référentielles et aux
contraintes existentielles,
·
et finalement une machine abstraite de bases de données.
Dans un espace de
stockage informatique, un objet peut être désigné par l’adresse du lieu qu’il
occupe : c’était le moyen traditionnel utilisé dans les systèmes de gestion de
fichiers. C’est un moyen frustre qui n’est pas intéressant au niveau des SGBD
car le lieu de stockage d’un objet peut changer pour des raisons d’exploitation
(recopie de disques, nettoyage des espaces vides, réorganisation physique…).
Aussi, les SGBD n’utilisent-ils pas les adresses pour désigner les
objets : ces adresses sont même inaccessibles autant aux développeurs
qu’aux concepteurs et aux personnes travaillant avec la base. Seul le SGBD a
accès aux adresses.
Les SGBD
utilisent une autre technique pour désigner les objets : celle de l’identifiant obligatoire de classe. Un
identifiant obligatoire d’une classe est formé d’un ou de plusieurs attributs
et
·
tout objet de la classe doit prendre une valeur claire pour lui,
·
deux objets de la même classe ne peuvent prendre la même valeur pour lui.
C’est le SGBD qui
assure la correspondance entre cette valeur et l’adresse de l’objet.
Il y a deux types
d’identifiant obligatoire d’une classe :
·
les clés (c’est le cas des SGBD « relationnels »)
·
ou les identificateurs d’objets (c’est le cas des SGBD
« objet »).
Pour associer un
objet d’une classe C à un objet d’une autre classe C’, les SGBD demande de
rajouter aux attributs de C, l’identifiant obligatoire de C’: ainsi tout objet
de C prenant une valeur claire pour cet identifiant, est associé à l’objet de
C’ désigné par cette valeur. Ils implémentent ainsi un chemin d’accès de la classe C à la classe C’. Il est monovalué car
un objet de C ne peut prendre qu’une valeur pour l’identifiant obligatoire de
C’ et donc ne correspondre qu’à un seul objet de C’.
Soit l’exemple
d’un véhicule et de son propriétaire : la classe Personne contient les
attributs : oidPersonne, son identificateur d’objet, NoPdc, le numéro de
permis de conduire, qui est un autre identifiant obligatoire de Personne,
NomPersonne, Adresse :
PERSONNE
(oidPersonne / NoPdc // NomPersonne, Adresse).
La classe
Véhicule est celle du chapitre précédent :
VÉHICULE (oidVéhicule / NoChâssis / NoVéhicule /
NoMoteur // Catégorie Marque DateCirculation).
Pour stocker le
fait que tel véhicule a comme propriétaire telle personne, il faut rajouter aux
attributs de Véhicule, l’identifiant obligatoire de Personne et donc :
- soit son
identificateur d’objets dans le monde objet :
VÉHICULE (oidVéhicule / NoChâssis / NoVéhicule /
NoMoteur // Catégorie Marque DateCirculation oidPersonne),
- soit sa clé
obligatoire dans le monde relationnel :
VÉHICULE (oidVéhicule / NoChâssis / NoVéhicule /
NoMoteur // Catégorie Marque DateCirculation NoPdc).
Dans un cas comme
dans l’autre, le principe est le même :
un objet de
Véhicule prend une valeur v pour
l’attribut oidPersonne ou pour l’attribut NoPdc ; à l’aide de cette valeur
v, le SGBD fait la correspondance
avec l’adresse de l’objet de Personne ainsi désigné et peut aller le
rechercher ; un SGBD « relationnel » va utiliser l’index associé
à la clé obligatoire NoPers pour retrouver l’objet.
Les SGBD assurent
le passage d’un objet d’une classe à un objet d’une autre classe par l’un de
ces deux mécanismes :
·
la navigation pour les SGBD « objet »,
·
et la jointure, pour les SGBD « relationnels ».
Dans le cas de la
navigation, on indique le parcours de la navigation en précisant les classes et
les attributs associatifs : ainsi pour retrouver l’adresse et le nom du
propriétaire d’un véhicule, on indique la classe Véhicule, l’attribut
oidPersonne de cette classe et la classe Personne.
Dans le cas de la
jointure, on indique les classes concernées : Véhicule * Personne. Le SGBD
associe alors les objets de Véhicule et ceux de Personne qui prennent des
valeurs identiques pour les attributs communs aux deux classes : NoPdc.
Chemins d’accès inverses
Le chemin d’accès
monovalué a permis d’associer un objet de Véhicule avec un objet de Personne
qui représente son propriétaire et ainsi de retrouver le propriétaire d’un
véhicules. Maintenant comment peut-on retrouver les véhicules dont une personne
est propriétaire. C’est la question du chemin d’accès inverse au chemin d’accès
précédent.
Les SGBD munis
d’un mécanisme de jointure comme les « relationnels » utilisent
l’index construit sur l’attribut de la clé obligatoire NoPdc dans la classe
Véhicule, pour implémenter le chemin d’accès inverse multivalué qui va de Personne
à Véhicule.
Pour les SGBD
avec la navigation, comme les SGBD « objet », il faut préciser le
chemin d’accès dans la définition des classes, sinon pour trouver les véhicules
d’une personne, il faut parcourir séquentiellement tous les objets de Véhicule
et ne retenir que ceux qui sont associés à l’objet du propriétaire ! Bien
sûr si la classe Véhicule contient beaucoup d’objets, les performances de cet
algorithme seront médiocres. Aussi faut-il créer un chemin d’accès inverse au
niveau de la classe Personne, en rajoutant un attribut associatif multivalué.
On obtient alors les classes suivantes :
PERSONNE (oidPersonne /
NoPdc // NomPersonne, Adresse, oidVéhicule*),
VÉHICULE (oidVéhicule /
NoChâssis / NoVéhicule / NoMoteur // Catégorie, Marque, DateCirculation, oidPersonne).
Alors, du point
de vue informatique, on stocke alors deux fois le fait que telle personne est
le propriétaire de tel véhicule :
·
dans l’objet v de Véhicule :
v = (oidv, -, -, -, -, -, -, oidp),
·
dans l’objet p de Personne :
p = (oidp, 1023, ?, ?, {oidv}).
Ainsi il y a de
la redondance au niveau informatique, dont il faut assurer la cohérence, tant
lors de la création des objets que lors des mises à jour (comme lors du
changement de propriétaire d’un véhicule).
Normalement c’est
au SGBD d’assurer la validation de cette redondance. S’il ne le fait pas, alors
ce sont aux développeurs de perdre leur temps à le faire.
Utilité des chemins d’accès inverses
De manière
générale, on peut supposer qu’à tout chemin d’accès correspond son chemin
d’accès inverse, comme le montre la figure suivante, où les noeuds sont
associés aux classes et les arcs aux chemins d’accès, les arcs marqués d’une
simple flèche correspondant aux chemins d’accès monovalués et les arcs marqués
d’une double flèche aux multivalués :
Mais à cause du
coût supplémentaire dû à la validation de la redondance induite par les chemins
d’accès inverses, il peut s’avérer indispensable de minimiser les chemins
d’accès inverses. Dans le cas où un chemin d’accès serait monovalué, c’est bien
sûr le chemin d’accès multivalué que l’on cherche éventuellement à éviter.
Ainsi dans l’exemple précédent, on peut s’interroger s’il ne serait pas
suffisant d’avoir simplement :
Quelles sont
parmi toutes les opérations de base : création et suppression d’objets de
Véhicule et de Personne, mise à jour du propriétaire d’un véhicule, accès aux
véhicules d’une personne, accès au propriétaire d’un véhicule, celles qui ont
une importance pour savoir si le chemin d’accès Véhicules de est inutile ?
Les seules
opérations de base : suppression d’un objet de Personne et
d’accès aux véhicules d’une personne. En effet, faire l’une de ces deux
opérations sans le chemin d’accès inverse, demande de parcourir en séquentiel
tous les objets de Véhicule ; par contre les performances des autres
opérations de base ne sont pas concernées.
Soit l’exemple
suivant, un véhicule peut assurer plusieurs trajets et un trajet être assuré
par plusieurs véhicules. C’est alors une association entre les classes Véhicule
et Trajet avec une paire de chemins d’accès multivalués.
Une telle
association ne peut être prise en compte directement dans les SGBD de type
« relationnel » car ces SGBD exigent que l’un des chemins d’accès
soit monovalué à cause de la forme normale des classes.
Avec un SGBD
« objet » en utilisant des chemins d’accès multivalués on peut
obtenir le schéma correspondant au graphe suivant :
Avec un SGBD de type
« relationnel », on va devoir créer une classe Transport dont les
objets vont contenir les associations entre les véhicules et les trajets :
Dans ce cas pour
trouver les objets de Trajet associés à un véhicule, on utilise le chemin
d’accès Les trajets, qui fournit les
objets de Transport associés au véhicule, et pour chacun d’eux on trouve
l’objet de Trajet concerné avec le chemin d’accès le trajet.
Intégrité référentielle
Dans l’exemple
des classes Véhicule et Personne, si l’intégrité référentielle est respectée, à
tout objet de Véhicule prenant une valeur claire v pour NoPdc ou pour oidPersonne, correspond un objet de Personne
identifié par la valeur v. Ainsi si
l’on veut obtenir toutes les valeurs identifiantes de la classe Personne, il
suffit d’interroger la classe Personne : sans l’intégrité référentielle,
il faudrait aussi interroger la classe Véhicule pour être sûr d’avoir une
réponse complète. Cela peut sembler « normal » que l’on puisse parler
d’une personne dans la classe
Véhicule seulement si cette personne existe
bien dans Personne. Mais, au niveau informatique, il n’y a rien de
« normal » : tout doit être pensé et programmé.
De manière
générale, voici le principe de l’intégrité référentielle : si une
classe C contient un chemin d’accès monovalué vers une classe C’, alors
·
si un objet de C prend une valeur claire v pour les attributs de l’identifiant obligatoire de C’, alors il
doit effectivement exister un objet de C’ prenant la même valeur identifiante v ;
·
si on supprime un objet de C’, de valeur identifiante v, alors on transforme la valeur v en valeur obscure dans tous les objets de C.
Si le SGBD
utilisé ne vérifie pas systématiquement cette intégrité référentielle, alors
nous vous conseillons fortement de faire les développements informatiques
nécessaires à sa validation systématique. La base de données est alors plus
fluide dans sa compréhension des associations.
Comme on peut le
remarquer, l’intégrité référentielle s’applique tout autant aux SGBD
« relationnels » qu’ « objet ».
Intégrité existentielle
L’intégrité
existentielle est une intégrité référentielle plus exigeante.
La classe C est
en intégrité existentielle avec la classe C’ si :
·
la classe C contient un chemin d’accès monovalué vers la classe C’,
·
elle est en intégrité référentielle avec C’,
·
et tout objet de C ne peut exister dans la base que si
-
il est toujours associé à un objet de C’,
-
et il est toujours associé au même objet de C’.
Remarque :
si C est en intégrité existentielle avec C’, C’ est en intégrité existentielle
avec C’’, alors est en intégrité existentielle avec C’’. La relation
d’intégrité existentielle est transitive.
Un SGBD qui
vérifie que C est en intégrité existentielle avec C’ garantit que :
·
lors de la création d’un objet de C, cet objet est associé à un objet de
C’,
·
la modification de l’association de cet objet avec l’objet de C ? est
interdite,
·
lors de la suppression d’un objet de C’, tous les objets de C qui lui sont
associés sont également supprimés.
Alors que
l’intégrité référentielle est applicable pour toute association, c’est au
concepteur de la base qui doit préciser quand le SGBD doit valider l’intégrité
existentielle en plus de l’intégrité référentielle.
L’intégrité
existentielle est très ancienne dans le domaine des SI : l’exemple
classique est celui de la classe Ligne-de-Commande
qui est en intégrité existentielle avec la classe Commande :
Commande
(NoCommande // NoClient MontantCommande DateCommande)
Ligne-de-Commande
(NoCommande NoLigne // NoProduit NombreProduits).
Un objet de Ligne-de-Commande existe dans la base
seulement s’il est associé à un objet de Commande et s’il lui reste toujours
associé.
Dans le monde
relationnel, il existe une manière d’implanter dans le schéma l’intégrité
existentielle de C avec C’ : il suffit que l’identifiant obligatoire de C
contienne celui de C’, comme dans le cas de Ligne-de-Commande (NoCommande,
NoLigne //) et Commande (NoCommande //)
Si les
concepteurs du SGBD que vous utilisez n’ont pas pris en compte l’intégrité
existentielle, alors nous vous conseillons fortement de la valider par
vous-même, pour la cohérence du SI et pour la limpidité qui en résulte pour
toutes les personnes travaillant avec cette association. Bien sûr il faut alors
écrire les programmes de validation pour chaque intégrité existentielle. Même
s’ils ne sont pas compliqués, ils prennent du temps et, de plus, il est
difficile d’avoir la certitude que l’intégrité existentielle soit validée
partout. Aussi pour développer des SI, mieux vaut-il travailler avec des SGBD
la prenant en compte.
Intégrité référentielle étendue
Reprenons
l’exemple précédent légèrement modifié :
PERSONNE
(oidPersonne / NoPdc // NomPersonne Adresse oidVéhicule*),
VÉHICULE
(oidVéhicule / NoChâssis / NoVéhicule / NoMoteur // Catégorie Marque
DateCirculation oidPersonne NoPdc).
La modification
concerne l’introduction du numéro de permis de conduire NoPdc dans la classe
Véhicule. NoPdc est une autre clé de Personne. Alors pour tout objet de
Véhicule on peut avoir ainsi le numéro de permis de conduire du propriétaire
sans avoir à atteindre l’objet de Personne. Cette manière de faire peut avoir
des avantages autant pour des raisons de performances (on évite ainsi une
opération de lecture d’un objet de Personne) que pour des raisons de
confidentialité (on n’a pas besoin alors d’avoir les droits d’accès de
Personne) et partage d’informations (on ne rentre pas en concurrence avec des
traitements travaillant sur Personne).
Mais alors quand
on associe un objet de Véhicule à un objet de Personne, il faut s’assurer que
les deux objets prennent toujours les mêmes valeurs pour NoPdc : ce
mécanisme est facile à implanter dans un SGBD et, s’il ne l’est pas, des
développeurs peuvent le mettre en place pour les classes concernées sans que
les programmes à écrire ne soient compliqués.
Ces programmes de
validation sont tellement simples qu’ils peuvent être étendus à tous les
attributs monovalués communs de deux classes en intégrité référentielle.
Ainsi :
PERSONNE
(oidPersonne / NoPdc // NomPersonne Adresse oidVéhicule*),
VÉHICULE
(oidVéhicule / NoChâssis / NoVéhicule / NoMoteur // Catégorie Marque
DateCirculation oidPersonne NoPdc
NomPersonne).
Dans cette
situation, le mécanisme d’intégrité
référentielle étendue étend le mécanisme classique d’intégrité
référentielle en garantissant que :
·
si un objet de Véhicule est associé à un objet de Personne, alors ces deux
objets prennent toujours les mêmes valeurs pour les attributs communs NoPdc et
NomPersonne ;
·
la mise à jour de l’attribut NomPersonne, qui n’appartient à aucune clé de
la classe Personne, est interdite dans la classe Véhicule ; par contre,
dès qu’un objet p de Personne change
de valeur pour l’attribut NomPersonne, alors tous les objets de Véhicule
associés à p prennent cette nouvelle
valeur pour l’attribut NomPersonne.
Les cardinalités
À un véhicule
correspond au plus une personne qui est son propriétaire : c’est la
cardinalité maximale du chemin d’accès propriétaire.
Une personne est propriétaire d’au maximum 25 véhicules: c’est la cardinalité
maximale du chemin d’accès inverse de propriétaire.
La vérification de ces cardinalités maximales ne pose aucun problème aux SGBD.
Néanmoins on peut ne pas être sûr d’une cardinalité maximale : ainsi il se
pourrait qu’une personne fût propriétaire de 26 véhicules. Dans ce cas, mieux
vaut ne préciser aucune cardinalité maximale.
Bien sûr on peut
aussi préciser les cardinalités minimales : par exemple une personne pour
être prise en compte dans la base doit être propriétaire d’au moins une
voiture. Dans ce cas, la cardinalité minimale du chemin d’accès inverse de propriétaire est de 1 : la
vérification d’une cardinalité minimale ne pose aucun problème aux SGBD.
Comme dans la
norme SQL les associations sont des tables ou des identifiants obligatoires
d’une autre classe (= clé étrangère), les opérations définies sur une classe au
chapitre précédent s’appliquent aussi aux associations. Nous présentons
maintenant des opérations définies sur plusieurs classes à l’aide de l’exemple
GVA.
Jointure
Exemple: trouver les noms et prénoms des
chauffeurs travaillant le 31 octobre 2000 ?
select Nom, Prénom
from CHAUFFEUR, AFF-CHAUFFEUR
where CHAUFFEUR.NoAVS = AFF-CHAUFFEUR.NoAVS
and DateAff = 31-10-00;
Jointure externe
Exemple : quels
sont les horaires des chauffeurs le 31 octobre 2000?
select Nom, Prénom, HeureDébut, HeureFin
from AFF-CHAUFFEUR, CHAUFFEUR
where DateAff = 31-10-00 and
AFF-CHAUFFEUR.NoAVS (+) = CHAUFFEUR.NoAVS ;
Ainsi tous les
objets de CHAUFFEUR sont dans le résultat.
Autres jointures
Exemple : numéros des véhicules ayant circulé
dès leur mise en circulation ?
select NoVéhicule
from VEHICULE, AFF-VEHICULE
where VEHICULE.NoVéhicule = AFF- VEHICULE.NoVéhicule
and AFF-VEHICULE.DateAff =
VEHICULE.DateCirculation;
Exemple : noms et
prénoms des chauffeurs qui travaillent le 31 octobre 2000 ?
select Nom, Prénom
from CHAUFFEUR, AFF-CHAUFFEUR
where CHAUFFEUR.NoAVS = AFF-CHAUFFEUR.NoAVS
and DateAff = 31-10-00;
Ambiguïtés sur les attributs
Des attributs
apparaissant dans plusieurs classes peuvent porter des mêmes noms et alors être
sources d’ambiguïté. Une possibilité dans SQL est de préfixer l’attribut par le
nom de sa classe.
Exemple en
SQL :
select Nom, Prénom
from CHAUFFEUR, AFF-CHAUFFEUR
where CHAUFFEUR.NoAVS=AFF-CHAUFFEUR.NoAVS
and DateAff = 31-10-00;
Ambiguïtés
sur les relations
Des classes peuvent apparaître plusieurs fois dans
la même expression et alors provoquer des ambiguïtés. Une possibilité est alors
de les renommer.
Exemple : trouver
les chauffeurs nés le même jour?
select C1.Nom, C1.Prénom
from CHAUFFEUR C1, CHAUFFEUR C2
where C1.DateNaissance = C2.DateNaissance
and C1.NoAVS ¹ C2.NoAVS;
Maintenant nous
complétons la machine abstraite de bases de données du chapitre précédent pour
prendre en compte les associations et nous l’appelons graphe de chemins d’accès : c’est simplement un graphe dont
les noeuds correspondent aux classes et les arcs aux chemins d’accès, les arcs
marqués d’une simple flèche correspondant aux chemins d’accès monovalués, les
arcs marqués d’une double flèche aux multivalués. À chaque chemin d’accès
correspondent ses cardinalités minimale et maximale : si un chemin d’accès
reliant la classe C à la classe C’ admet comme cardinalité minimale 1 et comme
cardinalité maximale 1, alors C est en intégrité existentielle avec C’.
Un graphe de
chemins d’accès est dit canonique si
tout chemin d’accès admet son chemin d’accès inverse. Voici un exemple de
graphe de chemins d’accès :
Ces graphes de
chemins d’accès canonique sont pour nous des points de passage entre le monde
informationnel et le monde informatique. Nous nous en servons pour présenter
les associations dans le monde informationnel.
Un processus de
conception de bases de données considère d’abord un modèle conceptuel de la
base qui appartient au monde informationnel de la base, puis construit
l’architecture informatique de la base comprenant le schéma de classes de la
base. Il s’agit de pouvoir passer du monde informationnel au monde
informatique. De plus, un processus de rétro ingénierie, qui cherche à
comprendre comment fonctionne une base de données, entreprend la démarche
inverse : il considère d’abord l’architecture informatique des données, le
schéma de classes de la base puis tente d’en extraire un modèle conceptuel de
la base. Ainsi le recouvrement des concepts entre ces deux mondes du SI, son
monde informatique et son monde informationnel est très important. Nous allons
le construire à partir de la machine abstraite de base de données. Dans un
processus de conception, le monde informationnel doit fournir les informations
nécessaires à la construction de cette machine abstraite ; dans le
processus inverse, celui de rétro ingénierie, le monde informatique doit
remplir la machine abstraite de la base de données, qui doit ensuite être
interprétée dans le monde informationnel.
Passage d’un graphe de chemin d’accès à un
graphe de relations
Dans le monde
informationnel, nous nous intéressons à la logique des informations et non aux
stockages des informations et à leurs modes d’accès comme dans le monde
informatique. Aussi simplifions nous le graphe de chemins d’accès canonique de
la manière suivante :
·
à tout noeud du graphe du chemins d’accès canonique correspond un et un
seul noeud du graphe de relations associé à la même classe, et inversement ;
·
à toute paire de chemins d’accès inverses entre les classes C et C’
correspond une et une seule arête dans le graphe de relation entre les noeuds
des classes C et C’ de la manière suivante :
-
si les cardinalités minimale et maximale du chemin d’accès de C à C’ sont
égales à 1, et donc si C dépend existentiellement de C’, alors l’arête dans le
graphe de relation reliant le noeud de C à celui de C’ est orientée vers C’ et
elle est de type « A » pour « arborescente » ;
-
si la cardinalité maximale du chemin d’accès de C à C’ est égale à 1, alors
l’arête dans le graphe de relation reliant le noeud de C à celui de C’ est
orientée vers C’ et elle est de type « F » pour
« fonctionnelle » ;
-
si les cardinalités maximales du chemin d’accès de C à C’ et de son chemin
d’accès inverse sont supérieures à 1 (chemins d’accès multivalués) , alors
l’arête dans le graphe de relation reliant le noeud de C à celui de C’ n’admet
aucune orientation et elle est de type « B » pour « binaire».
La figure
suivante illustre ces transformations :
Les mécanismes de base relatifs aux
associations dans le monde informatique
Dans le
paragraphe précédent relatif au monde informatique nous avons présenté des
mécanismes de base liés aux associations : l’intégrité référentielle,
l’intégrité existentielle et les cardinalités minimales et maximales. Les deux
premières sont tellement importantes dans la compréhension d’une modélisation
qu’elles font partie intégrante du modèle informationnel. Quant aux
cardinalités, elles sont décrites dans le cadre du graphe de chemins d’accès.
Si l’intégrité
référentielle n’est pas respectée, alors pour trouver toutes les personnes prises en compte dans la base,
il faut faire l’union entre les personnes de la classe Personne et celles qui se trouvent dans la classe Véhicule ! Ainsi (règle transformation) dès qu’une classe
contient un identifiant d’une autre classe dans ses attributs, alors la
structure informatique correspondante doit vérifier l’intégrité référentielle
entre ces deux classes pour être fidèle à la modélisation informationnelle.
L’intégrité
existentielle est fondamentale au niveau informationnel : dans de très
nombreuses situations de modélisation de SI, elle est très utile et permet des
spécifications précises. Si l’ensemble des attributs des identifiants
obligatoires de C contient l’ensemble des attributs des identifiants
obligatoires de C’, alors la classe C est en intégrité référentielle avec la
classe C’. En effet :
·
créer un objet c de C demande de
fournir des valeurs claires pour tous les identifiants obligatoires de
C et donc pour tous les identifiants obligatoires de C’; à cause de
l’intégrité référentielle, il existe donc un objet c’ admettant ces valeurs claires comme valeurs identifiantes ;
·
si c’ est supprimé, alors, par le
fait du mécanisme d’intégrité référentielle, c doit prendre des valeurs obscures pour les attributs des
identifiants obligatoires de C’ ; mais alors c prendrait des valeurs obscures pour des identifiants obligatoires
de C ! Comme c’est impossible, c est
supprimé ;
·
comme on ne peut modifier les valeurs prises par c’ pour les attributs des identifiants obligatoires de C’, on ne
peut modifier les valeurs prises par c’
pour les attributs des identifiants obligatoires de C : ainsi c’ reste associé au même objet c de la classe C.
Les cardinalités
maximales égales à 1 sont prises directement en compte dans le graphe de
relations. Les autres doivent être précisées seulement si elles sont clairement
connues et ne doivent jamais être transgressées.
Attention ! Les cardinalités minimales, excepté celles qui
sont relatives aux dépendances existentielles, doivent être précisées le plus
tardivement possible dans un processus de développement de SI. En effet, il ne
faut pas oublier les décalages entre le monde vivant et le monde informationnel.
Ainsi, par exemple :
·
ce n’est pas parce qu’un match est associé à au moins deux équipes, que
forcément dans le SI, il ne puisse pas exister un objet match associé à aucune équipe, par exemple dans une phase
d’établissement du calendrier annuel des matchs ;
·
de plus ce n’est pas forcément parce qu’une équipe arrête la compétition
qu’il faut supprimer l’objet équipe :
sans doute on ne veut pas perdre la trace des matchs auxquels elle a participé.
Le but de ce
paragraphe est de montrer que dans le monde informationnel toute association
peut être prise en compte par une simple classe et qu’il est beaucoup plus
efficace de faire ainsi au niveau informationnel.
Association
n-m
C’est le cas de
l’association Course entre les
classes Véhicule et Trajet : elle est de type n-m car un même véhicule assure des courses relatives à plusieurs
trajets et un trajet est assuré par plusieurs véhicules.
Voici une première spécification (S1)
des classes Véhicule et Trajet :
Véhicule
(oidVéhicule / NoVéhicule // Nbkmparcourus (Assure : oidTrajet)*)
Trajet (oidTrajet / VilleDépart VilleArrivée //
Distancetrajet
(Est-assuré-par : oidVéhicule)*).
Voici le graphe
de relation :
En voici une seconde (S2) :
Véhicule
(oidVéhicule / NoVéhicule // Nbkmparcourus)
Trajet (oidTrajet
/ VilleDépart VilleArrivée // Distancetrajet)
Course
(oidVéhicule oidTrajet //).
Bien sûr Course dépend existentiellement de
Véhicule et de Trajet, selon la règle précédente.
Voici le graphe de relation :
Ces deux spécifications ont le même
pouvoir d’expression : tout fait qui peut être pris en compte par l’une,
peut l’être par l’autre.
Dans S1, on peut
avoir :
·
les véhicules (v1, no1, 120000, {t1, t2, t3}) et (v2, no2, 24000,
{t2, t3}),
·
les trajets (t1, Genève, Grenoble, 150, {v1}), (t2, Grenoble, Genève, 150,
{v1, v2}), (t3, Nadaillac, Estivals, 4, {v1, v2}),
et dans S2 :
·
les véhicules (v1, no1, 120000) et (v2, no2, 24000),
·
les trajets (t1, Genève, Grenoble, 150), (t2, Grenoble, Genève, 150), (t3,
Nadaillac, Estivals, 4),
·
et les courses (t1, v1), (t2, v1), (t3, v1), (t2, v2), (t3, v2).
Les faits
exprimés dans S1 et dans S2 sont équivalents. Pour comparer S1 et S2, nous
considérons les situations remarquables suivantes:
Situation 1 : pour chaque course, on veut
connaître son montant.
Cette situation
se rencontre souvent en cours de modélisation. Il faut rajouter l’attribut
MontantCourse.
Avec S1 il y deux
possibilités envisageables et même une troisième dans certains cas :
·
Véhicule (oidVéhicule / NoVéhicule // Nbkmparcourus, (Assure :
oidTrajet // MontantCourse)*) et
Trajet (oidTrajet / VilleDépart, VilleArrivée // Distancetrajet,
(Est-assuré-par : oidVéhicule)*).
·
Véhicule (oidVéhicule / NoVéhicule // Nbkmparcourus, (Assure :
oidTrajet)*) et Trajet (oidTrajet / VilleDépart, VilleArrivée //
Distancetrajet, (Est-assuré-par : oidVéhicule // MontantCourse)*).
·
Véhicule (oidVéhicule / NoVéhicule // Nbkmparcourus, (Assure :
oidTrajet // MontantCourse)*) et
Trajet (oidTrajet / VilleDépart, VilleArrivée // Distancetrajet,
(Est-assuré-par : oidVéhicule// MontantCourse)*).
Dans le premier
cas, il est plus facile de connaître le montant de la course à partir de
Véhicule que de Trajet ; dans le second cas c’est l’inverse ; dans le
troisième cas :
·
il y a de la redondance car on prend en compte 2 fois le montant de la
course, une fois dans Véhicule et l’autre fois dans Trajet ;
·
bien sûr, dans ce cas, c’est au moment des mises à jour de MontantCourse
qu’il faut valider cette redondance ;
·
elle facilite l’accès à l’information au détriment des performances des
mises à jour ;
·
c’est une possibilité d’implémentation qui est inintéressante au
niveau d’un modèle informationnel.
Donc seules
restent les deux premières possibilités : comment choisir puisqu’elles
se différencient seulement par leurs chemins d’accès ? En fait ce n’est
pas au niveau informationnel qu’il faudrait faire ce choix mais au niveau de
l’implémentation (graphe de chemins d’accès). Car ce choix n’est faisable
qu’avec l’aide d’estimations relatives aux chemins d’accès ; il faut
connaître les transactions, les interrogations de la base, leurs fréquences,
autant d’informations le plus souvent encore indisponibles quand on travaille
au niveau informationnel. Les modélisateurs sont mis dans une situation de choix prématuré (on leur demande une
décision alors qu’ils n’ont pas les informations pour choisir et qu’ils
pourraient les avoir plus tard).
Avec S2, il y a
une seule possibilité :
Véhicule
(oidVéhicule / NoVéhicule // Nbkmparcourus)
Trajet (oidTrajet
/ VilleDépart, VilleArrivée // Distancetrajet)
Course
(oidVéhicule, oidTrajet // MontantCourse).
Autant avec S1
qu’avec S2 il suffit de rajouter un attribut à une classe : c’est une
opération facile de modification de classe que doit permettre tout
environnement de support au développement de SI.
Par contre S1
place les modélisateurs devant une situation de choix prématuré.
S2 majore S1.
Situation 2 : pour chaque course, on veut
connaître son chauffeur.
Bien sûr cela
signifie qu’il existe une classe :
Chauffeur
(oidChauffeur / NoPdC // NomChauffeur) par exemple.
Avec S1, il
suffit de rajouter un attribut de domaine oidChauffeur dans Véhicule ou Trajet
(le choix étant de même nature que
précédemment) et ainsi obtenir
par exemple :
Véhicule
(oidVéhicule / NoVéhicule // Nbkmparcourus (Assure : oidTrajet //
MontantCourse oidChauffeur)*) et
Trajet (oidTrajet / VilleDépart VilleArrivée // Distancetrajet,
(Est-assuré-par : oidVéhicule)*).
Voici le graphe
de relation :
Avec S2, il
suffit de rajouter un attribut de domaine oidChauffeur dans Course :
Véhicule
(oidVéhicule / NoVéhicule // Nbkmparcourus)
Trajet (oidTrajet
/ VilleDépart VilleArrivée // Distancetrajet)
Course
(oidVéhicule oidTrajet // MontantCourse oidChauffeur).
Voici le graphe
de relation :
Comme
précédemment nous nous refusons de comparer les deux représentations graphiques
d’un point de vue ergonomique: par contre, la représentation graphique obtenue
dans S2 est plus précise que celle qui est dans S1 car elle indique clairement
que l’association porte sur Chauffeur et Course et non, seulement sur Véhicule
et Chauffeur; dans S1 on ne peut « voir » que Trajet est concerné par
l’association entre Véhicule et Chauffeur. D’autre part l’intégrité référentielle
est plus facile à vérifier dans S2 que dans S1.
Ainsi pour cette
situation, S2 majore S1.
Situation 3 : on veut modéliser le
fait qu’une personne a fait cette course.
Bien sûr cela
signifie qu’il existe une classe :
Personne
(oidPersonne / NoPasseport // NomPersonne).
Dans S1, il faut savoir que le concept de course est enfoui dans Véhicule : il faut donc créer
l’association entre Personne et Véhicule ! Dans S2, on va simplement faire
une association entre Personne et Course et comme cette association est
elle-même n-m car une personne peut
avoir fait plusieurs courses et une course avoir emporté plusieurs personnes,
on va obtenir la représentation graphique suivante avec une nouvelle
classe Passager:
De nouveau, la
situation S2 majore la situation S1.
Ainsi dans toutes
les situations considérées, la spécification S2 majore S1 au niveau du monde
informationnel. Ainsi nous proposons de ne jamais utiliser une notation
particulière pour les associations n-m :
toutes les associations n-m sont modélisées comme des classes à part entière.
Association 0-1
Soit la
modélisation suivante :
VEHICULE
(NoVéhicule // Catégorie Marque NoChâssis NoMoteur DateCirculation)
LIGNE (CodeLigne
// Catégorie TypeLigne ArrêtDépart ArrêtArrivée)
AFF-VEHICULE
(NoVéhicule Date // StatutVéhicule CodeLigne StatutAffectation) où
·
à un objet de Véhicule sont associés sa catégorie (« tramway, bus,
trolleybus, minibus »), sa marque, son numéro de châssis, sa date de mise
en circulation,
·
et à un objet de Ligne sont associés sa catégorie (« tramway, bus,
trolleybus, minibus »), son type de ligne (« linéaire,
circulaire »), les noms de ses stations de départ et d’arrivée,
·
et à un objet de Aff-Véhicule sont associés le numéro de véhicule concerné,
la date du jour, le statut du véhicule (« en service, en réserve, en
réparation, hors service »), le code de la ligne concernée, et le statut
de l’affectation (« provisoire, confirmée, en attente »).
La classe
Aff-Véhicule est en dépendance existentielle avec la classe Véhicule puisque sa
seule clé NoVéhicule, Date, qui est
donc obligatoire, contient la seule clé de Véhicule NoVéhicule. Il existe une association de type 0-1 entre Aff-Véhicule et Ligne, puisqu’à un objet de Aff-Véhicule
correspond au plus un objet de Ligne. Voici le graphe de relation de cette
modélisation :
Une autre modélisation possible est
la suivante :
VEHICULE (NoVéhicule // Catégorie Marque NoChâssis
NoMoteur DateCirculation)
LIGNE (CodeLigne
// Catégorie TypeLigne ArrêtDépart ArrêtArrivée)
VEHICULE-STATUT (NoVéhicule
Date // StatutVéhicule)
AFF-VEHICULE
(NoVéhicule Date // CodeLigne StatutAffectation) où
·
Aff-Véhicule est en dépendance existentielle avec Véhicule-Statut
·
et il existe une association 0-1
entre Véhicule-Statut et Aff-Véhicule.
Voici le graphe de
relation de cette modélisation :
Comment comparer
ces deux modélisations ? Les deux sont équivalentes du point de vue de
leur pouvoir d’expression : tout fait que l’un peut prendre en compte,
l’autre le peut également. Toutes les deux garantissent qu’à une date donnée un
véhicule n’est associé qu’à une ligne. Dans la première, la classe Aff-Véhicule
contient autant des attributs de l’association d’un véhicule donné et d’une
date donnée avec une ligne donnée (StatutAffectation) que des attributs qui sont
indépendants de cette association (StatutVéhicule). Par contre la seconde les
sépare en deux classes qui ont des identifiants identiques.
Considérons cette
situation générique : si en approfondissant l’analyse du domaine, on
s’aperçoit qu’en fait un véhicule peut très bien être affecté à plusieurs
lignes la même date, alors
·
dans le cas de la deuxième modélisation, il suffit de modifier la clé de la
classe Aff-Véhicule en NoVéhicule, Date,
CodeLigne,
·
alors que, dans le cas de la première modélisation, il faut en fait la
transformer dans la seconde !
Pensez alors à
toutes les associations, méthodes et transactions qui ont été décrites dans les
termes de la première modélisation et qu’il va falloir modifier, et sans doute
vous partagerez notre avis : les associations 0-1 sont modélisées comme des classes à part entière.
Conclusion
Finalement, pour
obtenir des modélisations les plus facilement modifiables, mieux vaut suivre la
proposition suivante : toutes les
associations sont modélisées comme des classes à part entière.
Composition naturelle
La composition
(naturelle) des deux classes R et S, notée RS = R * S, est une nouvelle classe
RS qui
·
est formée sur l’union des attributs : RS+ = R+ È S+,
·
et vérifie : RS = R * S = { rs | rs.R+ Î R et rs.S+ Î S}.
L’ensemble des
attributs communs Ch+ = R+
Ç S+
est la charnière de la composition.
Deux objets r de
R et s de S sont composables si s’ils prennent les mêmes valeurs claires pour
les attributs de la charnière : r.Ch+ = s.Ch+.
La composition de
deux objets composables donne un nouvel objet rs de RS tel que :
rs.R+
= r. R+ et rs.S+ = s.S+.
Exemple: trouver les noms et
prénoms des chauffeurs travaillant le 31 octobre 2000 ?
(CHAUFFEUR *
AFF-CHAUFFEUR) [DateAff = 31-10-00] [Nom Prénom]
L’opération de composition est commutative et associative :
(R * S) = (S * R) et (R * S) * T = R * S * T.
Composition externe
RS = R *+
S, la composition externe des deux classes R et S, est une nouvelle classe RS
telle que:
RS+ = R+ È S+
RS = R*+S = {rs | rs.R+ÎR et (rs.S+ÎS ou rs.S+- Ch+=!)}
avec ! valeur obscure.
Exemple : quels sont les horaires des chauffeurs le 31 octobre 2000?
(CHAUFFEUR *+
AFF-CHAUFFEUR) [DateAff=31-10-00] [Nom Prénom HeureDébut HeureFin]
Ainsi tous les objets de CHAUFFEUR sont dans le
résultat.
La composition
externe n’est ni commutative ni associative.
Exemple
Soit les classes R(A//B) et S(C//B) et leurs différentes compositions.
R(A//B) |
S(C//B) |
R * S |
R *+ S |
a b a’ b a b’ |
c b c’ b |
a b c a’ b c a b c’ a’b c’ |
a b c a’ b c a b c’ a’b c’ a b’ ! |
Autres compositions
L’équi-composition de deux classes R et S par rapport aux
attributs CR+ et CS+ est une nouvelle classe RS = R
*(CR=CS) S telle que:
RS+ = R+ È S+
RS = (R * S) [CR+ = CS+]
Exemple: Numéro des Véhicules qui ont circulé
dès leur mise en circulation
(VEHICULE *
AFF-VEHICULE) [DateCirculation=DateAff] [NoVéhicule]
La théta-composition de deux classes R et
S par rapport au prédicat P est une nouvelle classe RS = R *(P) S telle
que :
RS+ = R+ È S+
R *(P) S = {rs | rs.R+ Î R et rs.S+ Î S et P(rs)} = (R * S) [P=vrai]
Exemple : les
noms et prénoms des chauffeurs qui travaillent le 31 octobre 2000 ?
(CHAUFFEUR *
AFF-CHAUFFEUR) [DateAff = 31-10-00] [Nom Prénom]
Le produit cartésien de deux classes R et
S est une nouvelle classe RS telle que :
RS = R ´ S = {(r, s) | r ÎR et sÎS}.
Des attributs apparaissant
dans plusieurs classes peuvent porter des mêmes noms et alors être sources
d’ambiguïté lors des compositions car celles-ci s’opèrent sur les attributs
communs. Cela demande ainsi une grande rigueur dans la dénomination des
attributs de classes : notamment il faut éviter de dénommer des attributs
avec des noms de domaine comme Date, Prix, Nom…
Exemple :
Commande (NoCommande // Date NoClient)
Livraison (NoCommande Date // NbProduitslivrés)
Commande *
Livraison va faire la composition en prenant comme charnière NoCommande Date et
ainsi considérer les seules livraisons ayant été effectuées le même jour que
leur commande.
Par contre
avec :
Commande (NoCommande // DateCommande NoClient)
Livraison (NoCommande DateLivraison // NbProduitslivrés)
alors Commande *
Livraison fait la composition de toutes les livraisons avec leurs commandes.
Des relations
peuvent apparaître plusieurs fois dans la même expression et alors provoquer
des ambiguïtés. On peut alors les renommer.
Exemple : trouver
les chauffeurs nés le même jour?
C := CHAUFFEUR
(C * CHAUFFEUR) [C:DateNaissance=DateNaissance Ù C:NoAVS ¹NoAVS] [C:Nom C:Prénom]
La partie du
monde vivant qui nous intéresse dans ce paragraphe est celle du langage des
personnes concernées, restreinte à ses concepts et aux phrases les plus
fréquentes utilisant ces concepts. Nous allons étudier cette partie à l’aide de
l’exemple GVA sur trois plans : celui du schéma de classes, celui de la
correspondance entre des faits du monde vivant et des objets de la base, et
celui de la correspondance entre des activités du monde vivant et des
opérations sur les objets, en nous limitant aux seules interrogations.
Un schéma de
classes comme celui de GVA, même muni des domaines des attributs, contient de
nombreuses ambiguïtés : ainsi, dans AFF-VEHICULE
(NoVéhicule DateAff // StatutVéhicule
CodeLigne StatutAffectation), une
ligne associée à une date donnée à un véhicule signifie que :
-
le véhicule assure en ce moment si la date est celle d’aujourd’hui, ou bien
a assuré cette ligne si la date est du passé ;
-
ou la planification en vigueur a affecté ce véhicule à cette ligne pour
cette date ;
-
ou l’affectation d’un véhicule de secours à telle ligne pour cette date.
En fait il est
bien normal que la sémantique précise se trouve au niveau du monde vivant et
qu’ensuite il faut tout un travail pour la conserver au niveau de
l’informatique. Aussi faut-il toujours accompagner les classes du monde
informationnel comme celles du monde informatique, d’un prédicat qui explique la constitution sémantique des objets de la
classe : c’est l’unique repère commun de tout un ensemble de personnes aux
responsabilités très variées qui vont travailler avec les objets des classes
autant les personnes du monde vivant que les personnes chargées du
développement du SI, de sa maintenance, de son développement. Une moindre
différence d’interprétation, une négligence dans le strict respect de ce
prédicat conduit à une divergence de plus en plus visible du contenu du SI et
contribue à affaiblir la confiance et sa pertinence.
Voici la liste
des classes et de leur prédicat de l’exemple GVA.
CHAUFFEUR
(Nom Prénom / NoAVS // Adresse DateNaissance Sexe
TotalHeures)
Pour chaque
chauffeur, identifié soit par son numéro AVS soit par son nom et prénom, on
conserve son adresse, sa date de naissance ainsi que son sexe. L'entreprise
“GVA” désire également conserver le nombre total d'heures de conduite de chaque
chauffeur.
PERMIS
(NoAVS Catégorie // DatePermis)
Il existe 3
catégories de véhicules: tramway, bus et trolleybus. Chaque chauffeur est
compétent pour une ou plusieurs catégories de véhicules. Lorsqu’un chauffeur
réussit un examen de conduite pour une catégorie de véhicules, on conserve la
date d'obtention du permis.
VEHICULE
(NoVéhicule // Catégorie Marque NoChâssis NoMoteur DateCirculation)
Chaque véhicule
est identifié par un numéro. On lui associe sa catégorie, sa marque, son numéro
de châssis, son numéro de moteur, ainsi que sa date de mise en circulation.
LIGNE
(CodeLigne // Catégorie TypeLigne
ArrêtDépart ArrêtArrivée)
Le réseau de
circulation est composé de lignes. Chaque ligne est identifiée par un code
pouvant être soit un numéro, soit une chaîne de caractères (ex :
AFF-VEHICULE
(NoVéhicule DateAff // StatutVéhicule
CodeLigne StatutAffectation)
L'affectation des
véhicules aux différentes lignes du réseau s'effectue quotidiennement. Ainsi,
un véhicule est associé pour un jour donné à une et une seule ligne; il est
évident que plusieurs véhicules sont affectés à une même ligne le même jour. Il
faut cependant souligner qu'un véhicule ne peut être utilisé sur une ligne que
si celui-ci est en état de marche le jour désiré. En effet, chaque jour, un
véhicule est soit disponible soit en réparation; lorsqu'un véhicule est affecté
à une ligne, il est soit actif (mis en service régulier), soit de réserve. Bien
entendu, la catégorie du véhicule doit correspondre à la catégorie de la ligne
: il est impensable d’affecter un tramway à une ligne de trolleybus.
AFF-CHAUFFEUR
(NoAVS DateAff // StatutChauffeur
NoSérie)
L'entreprise GVA
désire également gérer l’emploi du temps quotidien des chauffeurs. Un
chauffeur, pour un jour donné, est soit en congé (il ne peut donc être employé
ce jour-là), soit en service régulier, soit de réserve. De plus, pour un jour
donné, un chauffeur en service régulier
ne peut être affecté qu’à une et une seule série.
TRANCHE-SERIE
(NoSérie CodeLigne // HeureDébut HeureFin)
Une série est
identifiée par un numéro et elle concerne un ensemble de lignes distinctes
(c’est-à-dire une série ne peut pas contenir la même ligne plus d'une fois).
Pour chaque ligne d'une série, on connaît l'heure de début d'activité et
l'heure de fin d'activité.
L'exemple
ci-dessous illustre le cas des séries : la série 328 concerne les lignes 3, 4
et C. Le chauffeur “Boubou”, affecté à cette série le 24 juin 1991 débute à
6h12 sur la ligne 3 et termine à 21h00 sur la ligne C. Il travaille ainsi 7
heures et 13 minutes en tout.
HEURE-CHAUFFEUR
(NoVéhicule DateAff NoAVS // Nb-Heures)
Chaque jour, le
nombre d'heures de conduite d’un véhicule, effectuées par un chauffeur, est
stocké dans la base. Lorsqu'un chauffeur est en réserve, il peut être utilisé
pour conduire un véhicule si nécessaire. Dans ce cas, il devient chauffeur de
remplacement et on l'affecte directement à un véhicule et non à une série.
Quand on travaille à observer le
monde vivant, il est souvent très utile de travailler non seulement avec des
classes mais aussi avec un graphe de relations entre ces classes.
Voici celui du
schéma de GVA :
Nous constatons
que les liens existentiels entre classes sont construits entre deux classes
(comme Permis et Chauffeur) parce que les attributs des identifiants
obligatoires (NoAVS Catégorie) de l’une contient ceux de l’autre (NoAVS). Comme
cette relation de dépendance existentielle est transitive, les liens existentiels
redondants (comme entre Heure-Chauffeur à DateAff) ne sont pas dans le graphe.
Les autres liens sont référentiels et proviennent de la présence d’un
identifiant obligatoire d’une autre classe (ex : Série) dans les attributs
d’une première classe (ex : Aff-Chauffeur).
Il s’agit de
comprendre les décalages entre les objets stockés dans la base et les faits
constatés dans le monde vivant. Comme exercice d’appréhension de cette
difficulté, nous proposons l’exercice suivant : vous supposez que le
schéma de classes précédent soit celui de la base de données, que la base de
données vérifie toutes les intégrités existentielles, référentielles et
d’identifiants et vous répondez aux questions suivantes du monde vivant en
considérant seulement la base de données : est-il possible que
·
un véhicule soit toujours affecté à la même ligne ?
·
un véhicule soit toujours affecté au même chauffeur ?
·
un chauffeur soit affecté à plusieurs véhicules le même jour ?
·
un véhicule ait été affecté à la ligne 5 puis à la ligne 9 le même
jour ?
·
l’on puisse connaître tous les véhicules circulant sur la ligne 5,
aujourd’hui?
·
le chauffeur Dupont soit toujours affecté à la même ligne ?
Quand une
personne remplissant une activité a besoin d’interroger la base, elle a d’abord
une question dans son langage :
Le cadre du
travail est généralement le suivant :
·
établir la liste des classes concernées,
·
construire la composition des classes,
·
déterminer les opérations de sélection (sélection
de la composition),
·
déterminer les attributs du résultat (projection
de la composition),
·
écrire l’interrogation dans le langage relationnel,
·
comprendre le sens des réponses obtenues, qui se trouve dans le sens de la
classe obtenue par composition.
·
écrire l’interrogation dans le langage du SGBD et en fonction du schéma de
classes de la base de données.
Exemple de GVA : trouver les noms et prénoms des
chauffeurs travaillant le 31 octobre 2000 ?
- en langage
relationnel :
(CHAUFFEUR *
AFF-CHAUFFEUR) [DateAff = 31-10-00] [Nom, Prénom]
- en SQL :
select Nom, Prénom
from CHAUFFEUR, AFF-CHAUFFEUR
where CHAUFFEUR.NoAVS = AFF-CHAUFFEUR.NoAVS
and DateAff = 31-10-00;
Exercices :
·
associer à chaque série toutes les catégories de ses lignes ;
·
trouver les véhicules conduits par tel chauffeur à telle date sans utiliser
la classe Heure-Chauffeur.
Vous supposez que
le schéma de classes précédent soit celui de la base de données, que la base de
données vérifie toutes les intégrités existentielles, référentielles et
d’identifiants et vous répondez aux questions suivantes du monde vivant en
considérant seulement la base de données : est-il possible que
-
un véhicule soit toujours affecté à la même ligne ?
Réponse : Oui
La classe
concernée est AFF-VEHICULE d’identifiant NoVéhicule DateAff :
aucune intégrité n’interdit que tous les objets de AFF-VEHICULE relatifs à ce véhicule
de prendre la même valeur pour l’attribut CodeLigne.
-
un véhicule soit toujours affecté au même chauffeur ?
Réponse : Oui
La classe
concernée est HEURE-CHAUFFEUR d’identifiant
(NoVéhicule DateAff NoAVS). Aucune intégrité n’interdit que tous les
objets de HEURE-CHAUFFEUR prenant une même valeur pour NoVéhicule, prennent
tous la même valeur pour NoAVS identifiant de Chauffeur.
-
un chauffeur soit affecté à plusieurs véhicules le même jour ?
Réponse : Oui
La classe concernée est HEURE-CHAUFFEUR d’identifiant
(NoVéhicule DateAff NoAVS) : l’intégrité de l’identifiant de
HEURE-CHAUFFEUR permet justement d’avoir plusieurs objets prenant les mêmes
valeurs pour DateAff et pour NoAVS avec des valeurs différentes pour
NoVéhicule.
-
un véhicule ait été affecté à la ligne 5 puis à la ligne 9 le même
jour ?
Réponse : Oui
La classe
concernée est AFF-VEHICULE d’identifiant NoVéhicule DateAff : à
cause de l’intégrité des identifiants, on sait qu’à tout instant, dans la base,
à un véhicule et à une date donnée correspond une seule ligne. Donc, dans la
base, aucun véhicule ne peut être associé à la fois à la ligne 5 et à la ligne
9 pour la même date. MAIS, rien n’interdit la mise à jour de la valeur prise
par l’objet pour l’attribut CodeLigne : ainsi l’objet a pu prendre la
valeur 5, puis la valeur 9 !
-
l’on puisse connaître tous les véhicules circulant sur la ligne 5
aujourd’hui ?
Réponse : Non ou partiellement
oui
La classe
concernée est AFF-VEHICULE et la réponse semble
évidente :
AFF-VEHICULE
[CodeLigne = 5] [NoVéhicule].
Mais avec la question précédente, on sait
qu’avec ce schéma, des véhicules ont pu circuler sur la ligne 5 puis sur une
autre ligne, et que la base n’a pas la trace de l’information : si ce cas
survenait, alors AFF-VEHICULE[CodeLigne=5] [NoVéhicule] ne fournirait qu’une
réponse partielle. Ainsi le monde informatique ne peut garantir une réponse
complète au monde vivant.
-
le chauffeur Dupont soit toujours affecté à la même ligne ?
Réponse : finalement oui
Aucune classe
toute seule contient la sémantique de l’affectation d’un chauffeur à une ligne.
A priori cette question est hors sujet.
Il faut composer
les classes AFF-CHAUFFEUR et TRANCHE-SERIE pour
obtenir une association entre NoAVS et CodeLigne.
Le sens de AFF-CHAUFFEUR*TRANCHE-SERIE correspond à l’affectation d’un
chauffeur, un jour donné, à une série composée d’un certain nombre de
lignes : on peut penser alors
que tel chauffeur est affecté aux lignes de sa série pour tel jour.
Dans
ce cas pour que Dupont soit toujours affecté à la même ligne, il suffit qu’il
existe une série composée d’une seule ligne, toujours la même, et que Dupont
soit toujours affecté à cette série !
Associer à chaque série toutes les catégories
de ses lignes
Le cadre du
travail est généralement le suivant :
·
établir la liste des classes concernées : Tranche-Série et Ligne
·
construire la composition des classes : Tranche-Série * Ligne
·
déterminer les opérations de sélection (sélection
de la composition) : aucune ;
·
déterminer les attributs du résultat (projection
de la composition) [NoSérie Catégorie] ;
·
écrire l’interrogation dans le langage relationnel : (Tranche-Série *
Ligne) [NoSérie Catégorie] ;
·
comprendre le sens des réponses obtenues, qui se trouve dans le sens de la
classe obtenue par composition : le résultat associe une série à une
catégorie parce que la série contient au moins une ligne de cette catégorie.
·
écrire l’interrogation dans le langage du SGBD et en fonction du schéma de
classes de la base de données :
select NoSérie, Catégorie
from TRANCHE-SERIE, LIGNE
where TRANCHE-SERIE.CodeLigne = LIGNE. CodeLigne ;
Trouver
les véhicules conduits par tel chauffeur à telle date sans utiliser la classe Heure-Chauffeur
Le cadre du
travail est généralement le suivant :
·
établir la liste des classes concernées : il n’y a aucune classe autre
que Heure-Chauffeur, qui exprime l’association entre un chauffeur et un
véhicule à une date donnée ; il faut essayer une composition sur les
classes : Aff-Chauffeur, Série, Tranche-Série, Ligne, Aff-Véhicule ;
·
construire la composition des classes : Aff-Chauffeur * Série *
Tranche-Série * Ligne * Aff-Véhicule ;
·
déterminer les opérations de sélection (sélection
de la composition) : [NoAVS=xyz] [DateAff=date]
·
déterminer les attributs du résultat (projection
de la composition) : [NoVéhicule]
·
écrire l’interrogation dans le langage relationnel (Aff-Chauffeur *
Série * Tranche-Série * Ligne * Aff-Véhicule ) [NoAVS=xyz] [DateAff=date]
[NoVéhicule]
·
comprendre le sens des réponses obtenues, qui se trouve dans le sens de la
classe obtenue par composition : on associe alors un chauffeur à une date
donnée avec un véhicule parce que (Aff-Véhicule) ce véhicule circule à cette
date-là sur une ligne qui (Tranche-Série) fait partie de la série
(Aff-Chauffeur) attribuée à ce chauffeur à cette date. Mais rien ne dit que ce
chauffeur a conduit ce véhicule car en fait la réponse va associer à ce
chauffeur tous les véhicules
circulant sur n’importe laquelle des lignes de la série du chauffeur ! Le
sens de cette réponse n’est pas celui de la question.
Cette interrogation de la base ne correspond pas à la question initiale.
Une règle d’intégrité est un concept
informatique qui désigne simplement une condition logique qui doit toujours
être vérifiée. Son but informatique est de maintenir la cohérence des données
stockées dans la base. Elle nécessite des contrôleurs,
qui sont des programmes particuliers :
L’implémentation de règles d’intégrité
nécessite :
Le concept de règle d’intégrité joua un
rôle décisif dans le succès de l’informatique des organisations dans les années
1960 car il permit de contrôler la cohérence des données stockées dans des
fichiers informatiques avec une rigueur et précision incomparables avec celle
des fichiers mécanographiques ou sur support papier. Et de plus cette cohérence
pouvait profiter non pas seulement à un seul traitement mais à plusieurs.
Maintenant l’informatique des
organisations a pris une dimension beaucoup plus large, celle des SIC. Or un
SIC doit sa légitimité dans son support aux activités de l’institution. Mais
une institution n’a aucune règle d’intégrité ; par contre elle a des règles de gestion qui servent à
coordonner les activités de différents services et de différents acteurs de
l’institution.
Aussi une règle d’intégrité d’un SIC
peut-elle contrôler :
Les règles d’intégrité d’un SIC sont
capitales pour sa compréhension et pour son adéquation aux activités de
l’institution d’un SIC.
Dans un premier temps, nous considérons
les règles d’intégrité comme des éléments du monde communicationnel. Nous les
définissons à l’aide de classes et d’associations et nous présentons une
manière de les spécifier en introduisant le tableau de portée des règles. Nous
définissons quatre types particuliers de règles d’intégrité : les règles
d’intégrité statiques et de comportement, les règles d’intégrité individuelles
et ensemblistes.
Dans un deuxième temps, nous
considérons les règles d’intégrité comme des éléments du monde informatique et
nous présentons comment des règles d’intégrité du monde communicationnel
peuvent être validées au niveau informatique.
Finalement dans un troisième temps,
nous nous intéressons au rapport entre règles d’intégrité et règles de gestion.
Nous mettrons ainsi en évidence des décalages entre le monde des activités et
le monde informatique.
Une règle
d'intégrité (ri) est une condition qui est :
Commentaire : si une règle d’intégrité du monde communicationnel est
implémentée dans le SI, alors :
Une règle d’intégrité est statique si elle s’applique à n’importe
quel état de la base ; elle est de
comportement ou dynamique, si
elle s’applique aux changements d’états.
Commentaire : si une règle d’intégrité est statique, alors à tout
moment il est possible de constater si un état du SI valide la règle
d’intégrité ou non, en dehors des traitements transformant le SI. Si un état du
SI ne valide pas la règle d’intégrité, cela veut dire qu’il existe un
traitement où la validation de la règle se fait de manière erronée.
Par contre, dans le cas d’une règle
d’intégrité dynamique, sa validation se fait obligatoirement pendant
l’exécution d’un changement d’états : il est alors impossible de détecter
une transgression simplement en observant un état du SI comme dans le cas d’une
règle d’intégrité statique.
Le contexte
d'une règle d'intégrité désigne les classes sur lesquelles la règle d'intégrité
est définie.
La portée
d'une règle d'intégrité ri désigne l'ensemble des primitives de modification de
classes, qui doivent contenir un contrôleur de ri, pour que tout état du SI
validant ri soit transformé par cette primitive en un autre état validant ri.
La réponse
d'une règle d'intégrité ri indique les actions à entreprendre en cas de
transgression de ri. La réponse la plus commune est le refus de l'exécution de
la primitive, et, par voie de conséquence, du traitement qui avait besoin de
l’exécution de cette primitive.
L'expression
d'une règle d’intégrité décrit la règle d’intégrité en langue naturelle, grâce
aux prédicats des classes du contexte de la règle d’intégrité. Ensuite il faut
lui donner une formulation rigoureuse et sans ambiguïté, notamment à l’aide
d’expression formelle relationnelle ou de différents types de règle
d’intégrité.
Exemple AffPersProjet
Soit les classes:
Personne (NoPers // Xpers),
Qualification (NoQualif // Xqualif),
Projet (NoProjet // Xprojet),
Compétence (NoPers NoQualif // Xcompétence), indiquant
les qualifications acquises d’une personne, en dépendance existentielle avec
Personne et Qualification,
QualifRequise (NoProjet NoQualif // Xqualifrequise),
indiquant les qualifications requises d’un projet, en dépendance existentielle
avec Qualification et Projet,
Affectation (NoPers NoProjet // Xaffectation), indiquant
que telle personne est affectée à tel projet, en dépendance existentielle avec Personne
et Projet,
Xpers, Xqualif, Xprojet, Xcompétence, Xqualifrequise,
Xaffectation étant des listes d’attributs.
Voici le graphe de classes :
Graphe de classes de AffPersProjet
Voici l’expression d’une règle
d’intégrité (QualifAffect) :
" affectation =
(nopers, noprojet) Î Affectation :
cardinalité {(Affectation * Personne * Compétence *
Qualification) [NoProjet = noprojet, NoPersonne = nopers] [NoQualif]
Ç
(Affectation * Projet * QualifRequise * Qualification)
[NoProjet = noprojet, NoPersonne = nopers] [NoQualif]} ³ 2.
On peut aussi l’écrire ainsi :
Pour toute affectation
= (nopers, noprojet) de
Affectation :
le nombre de
qualifications communes à
(Affectation * Personne * Compétence * Qualification)
[NoProjet = noprojet, NoPersonne = nopers] [NoQualif]
et à
(Affectation * Projet * QualifRequise * Qualification) [NoProjet = noprojet,
NoPersonne = nopers] [NoQualif]
doit être supérieur à 2.
Toute personne affectée à un projet
doit avoir dans ses compétences au moins 2 des qualifications requises par ce
projet.
La portée de cette règle :
Dans le chapitre sur les associations,
nous avons défini l’intégrité référentielle et l’intégrité existentielle. Ce
sont des règles d’intégrité particulières. Comme du reste également le sont
aussi les identifiants d’une association ou d’une classe, et les règles
concernant les domaines des attributs.
Une règle d'intégrité est individuelle si elle porte sur un seul
objet d’une seule classe; alors sa validation portera seulement sur cet objet.
Par contre une règle d'intégrité est ensembliste
si elle porte sur plusieurs objets; sa validation porte alors sur des
objets qui ne sont pas connus au moment de son déclenchement.
Exemple
Personne (NoPers // DateEmbauche
DateNaissance),
Affectation (NoPers NoProjet //),
Compétence (NoPers NoQualif //
DateAcquisition).
Voici la règle
d’intégrité suivante (Dembauche) : la date d’embauche d’une personne à un projet est postérieure à sa date
de naissance.
" pers Î Personne : pers[DateEmbauche] ³ pers[DateNaissance].
Cette règle d’intégrité est définie sur
Personne ; c’est un règle individuelle statique.
Voici une autre règle d’intégrité
(DCompétence) : la date
d’acquisition d’une compétence par une personne est postérieure à sa date
d’embauche.
" cp Î Personne * Compétence :
cp[DateAcquisition] ³ cp[DateEmbauche].
Cette règle d’intégrité est définie sur
Personne et Compétence ; c’est une règle ensembliste statique.
Voici une autre règle d’intégrité
(MaxPers) : tout projet a au maximum 10
personnes qui lui sont affectées.
" noprojet Î Affectation[NoProjet] :
cardinalité
(Affectation[NoProjet=noprojet] [NoPers]) £ 10.
Voici une autre règle
d’intégrité (+Jeune): toute nouvelle
personne affectée à un projet doit être plus jeune que la moyenne d’age des
personnes déjà affectées à ce projet.
" nouveau
(nopers, noprojet) de Affectation :
moyenne ( (Affectation * Personne)
[NoProjet=noprojet] [DateNaissance]) ³
Personne[NoPers=nopers] [DateNaissance].
Cette règle d’intégrité est définie sur
Affectation et Personne : c’est une règle d’intégrité dynamique et
ensembliste.
Elle est dynamique car il est
impossible de détecter une transgression simplement en observant les objets de
Affectation. Elle est ensembliste, car elle demande de parcourir les objets de
Affectation pour retrouver tous les objets du projet concerné.
Remarque : si la classe Affectation contenait l’attribut DateAffectation,
alors la règle d’intégrité précédente serait statique.
Une règle
d’intégrité définie dans le schéma communicationnel représente comme une
assurance que certains états incohérents de la base ne pourront jamais être
atteints. Bien sûr cette assurance a un prix :
·
celui de ralentir le développement des traitements ;
·
celui de ralentir l’exécution des traitements.
En effet, la
validation des règles ne fait qu’éviter des incohérences et pour tous les cas
où les traitements évitent d’eux-mêmes les situations d’incohérence, alors la
validation des règles est inutile. Elle n’est utile que pour les autres :
alors si l’on est optimiste, ces validations ne vont servir que dans peu de cas
et il faut y passer le moins de temps possible.
Or valider une
règle prend du temps. Il faut analyser la règle, construire son tableau de
portée. Ensuite il faut spécifier les contrôleurs des règles pour toutes les
situations de risque de transgression. Enfin il faut les implanter et les
tester. Puis, au moment de l’exploitation, l’exécution des traitements sera
ralentie par le déclenchement de ces contrôleurs, qui, si l’on est optimiste,
ne vont découvrir que peu de transgressions.
Aussi faudra-t-il
prendre une décision d’architecture informatique : quelles seront les
règles d’intégrité du schéma communicationnel qui seront effectivement
implémentées.
Comme le tableau
de portée des règles d’intégrité le montre, ce sont plusieurs primitives qui
sont susceptibles de transgresser la règle d’intégrité : la validation de
règle d’intégrité va demander la mise en place de plusieurs contrôles
d’intégrité.
L’exigence concernant la validation de
toutes les règles d’intégrité retenues pour l’implémentation est de garantir
aux personnes travaillant avec le SI que :
Aussi la validation des règles d’intégrité retenues pour
l’implémentation demande-t-elle de réelles compétences en informatique pour
être d’une part fiable et d’autre part performante et d’être parfaitement
documentée.
La base de la démarche est alors le tableau de portée des
règles d’intégrité, comme nous allons l’expliquer à l’aide de l’exemple.
Dans un tableau de portée, les lignes
désignent les classes, les colonnes les règles d’intégrité, les cellules les
risques de transgression de la règle d’intégrité de la colonne pour une
primitive de classe de la ligne :
·
Créer indique le risque encouru lors de
la création d’un objet ;
·
Sup indique le risque encouru lors de
la suppression d’un objet ;
·
Maj Attr indique le risque encouru lors
de la mise à jour de la valeur prise par un objet pour l’attribut Attr.
Voici les classes de l’exemple
précédent :
Personne (NoPers // DateEmbauche
DateNaissance),
Projet (NoProjet // Xprojet),
Qualification (NoQualif // Xqualif),
Compétence (NoPers NoQualif //
DateAcquisition),
QualifRequise (NoProjet NoQualif //
Xqualifrequise),
Affectation (NoPers NoProjet // DateAffectation).
RI Classes |
QualifAffect |
Dembauche |
DCompétence |
MaxPers |
+Jeune |
Personne |
Æ |
Créer, maj
DateNaissance, maj DateEmbauche |
Maj DateEmbauche |
Æ |
Æ |
Projet |
Æ |
Æ |
Æ |
Æ |
Æ |
Qualification |
Sup |
Æ |
Æ |
Æ |
Æ |
Compétence |
Sup |
Æ |
Créer, maj
DateCompétence |
Æ |
Æ |
QualifRequise |
Sup |
Æ |
Æ |
Æ |
Æ |
Affectation |
Créer |
Æ |
Æ |
Créer |
Créer |
Ce tableau
se remplit en considérant que sont vérifiées toutes les dépendances
référentielles et existentielles, ainsi que les règles concernant les
identifiants primaires des classes et les domaines d’attributs. C’est la
raison pour laquelle la primitive créer
Projet ne se trouve pas dans la portée de QualifAffect : en effet, si
l’on cherche à créer un nouveau projet, alors il ne peut exister dans la base
aucune affectation à ce projet à cause de la dépendance existentielle
d’Affectation envers Projet. La règle QualifAffect ne peut donc être transgressée.
A chaque primitive, on fait
correspondre toutes les règles qui peuvent être transgressées lors d’une de ses
exécutions, y compris les dépendances existentielles, référentielles,
d’identifiants, de domaines. Pour chacune de ces règles, on associe
Soit la primitive créerAffectation qui
s’applique à un objet : affect = (nopers, noprojet, dateaff) ; une de
ses exécutions risque de transgresser les règles de :
Pour chacune d’elles, on va mettre en
évidence les espaces informationnels des tests ITest et des rèponses IRéponse
en cas de transgression, qui sont relatifs à la primitive créerAffectation.
identifiant primaire (IPAff)
L’espace informationnel de test est
celui des identifiants de Affectation déjà connus :
ITest(IPAff(créerAffectation)) =
IPAffectation.
L’espace informationnel de la réponse
est vide et contient comme
message : cet identifiant « nopers, noprojet » est déjà
connu :
IRép(IPAff(créerAffectation)) = Ø.
Msg(IPAff(créerAffectation)) =
« cet identifiant « nopers, noprojet » est déjà
connu ».
dépendance existentielle entre Affectation et
Personne (DEAffPers)
ITest(DEAffPers(créerAffectation)) =
IPPersonne.
IRép(DEAffPers(créerAffectation)) = Ø.
Msg(DEAffPers(créerAffectation)) = «
l’identifiant « nopers » est inconnu dans Personne ».
dépendance existentielle entre Affectation et
Projet (DEAffProj)
L’espace
informationnel de test est celui des identifiants de Projet déjà connus :
ITest(DEAffProj(créerAffectation))
= IPProjet.
L’espace
informationnel de la réponse est vide
et contient comme message : l’identifiant « noprojet » est inconnu
dans Projet :
IRép(DEAffProj(créerAffectation))
= Ø.
Msg(DEAffProj(créerAffectation))
= « l’identifiant « noprojet » est inconnu dans Projet ».
domaine de DateAffectation (DomDateAffectation)
L’espace
informationnel de test est vide :
ITest(DomDateAffectation
(créerAffectation)) = Ø.
iRép(DomDateAffectation
(créerAffectation)) = Ø.
Msg(DomDateAffectation
(créerAffectation)) = « la valeur « dateaff» n’est pas autorisée pour
l’attribut DateAffectation ».
QualifAffect
ITest(QualifAffect(créerAffectation))
= (Personne * Compétence) [NoPers = nopers] [NoQualif] + (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif].
IRép(QualifAffect(créerAffectation))
= (Personne * Compétence) [NoPers = nopers] [NoQualif] + (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif]
Msg(QualifAffect(créerAffectation))
=
« voici les
compétences de la personne : (Personne * Compétence) [NoPers = nopers]
[NoQualif] ; voici les qualifications requises du projet (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif]. La personne n’a pas assez de
compétences dans le domaine du projet ».
MaxPers
ITest(MaxPers(créerAffectation))
= Affectation[NoProjet=noprojet].
IRép(MaxPers(créerAffectation))
= Affectation[NoProjet=noprojet].
Msg(MaxPers(créerAffectation))
= « il y a déjà le maximum personnes affectées au projet
« noprojet » ».
+Jeune
ITest(+Jeune(créerAffectation)) =
(Affectation * Personne)[NoProjet=noprojet] [DateNaissance] +
Personne[Nopers=nopers] [DateNaissance].
IRép(+Jeune(créerAffectation)) =
Personne[Nopers=nopers] [DateNaissance] + moyenne(Affectation *
Personne)[NoProjet=noprojet] [DateNaissance].
Msg(+Jeune(créerAffectation)) =
« la personne identifiée par « nopers » est plus âgée que la
moyenne « moyenne(Affectation * Personne)[NoProjet=noprojet]
[DateNaissance] » des personnes affectées au projet
« noprojet » ».
Voici le tableau récapitulatif des
risques pour la primitive créerAffectation :
créerAffectation (nopers,
noprojet, dateaff) |
ITest |
IRép |
Msg |
IPAff |
IPAffectation |
Ø |
cet identifiant « nopers, noprojet » est déjà
connu |
DEAffPers |
IPPersonne |
Ø |
l’identifiant « nopersonne » est inconnu dans
Personne |
DEAffProj |
IPProjet |
Ø |
l’identifiant « noprojet » est inconnu dans Projet |
DomDateAffectation |
Ø |
Ø |
la valeur « dateaff» n’est pas autorisée pour
l’attribut DateAffectation |
QualifAffect |
(Pers.*Compétence) [NoPers = nopers] [NoQualif] + (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif] |
(Personne*Compétence) [NoPers = nopers] [NoQualif] + (Projet*QualifRequise) [NoProjet = noprojet] [NoQualif] |
voici les compétences de la personne : (Personne *
Compétence) [NoPers = nopers] [NoQualif] ; voici les qualifications
requises du projet (Projet * QualifRequise) [NoProjet = noprojet]
[NoQualif]. La personne n’a pas assez de compétences dans le domaine du
projet |
MaxPers |
Affectation [NoProjet=noprojet] |
Affectation [NoProjet=noprojet] |
il y a déjà le maximum de personnes affectées au projet
« noprojet » |
+Jeune |
(Affectation * Pers.) [NoProjet=noprojet] [DateNaissance] + Personne [Nopers=nopers]
[DateNaissance] |
Personne [Nopers=nopers] [DateNaissance] + moyenne (Affectation * Personne) [NoProjet=noprojet]
[DateNaissance] |
la personne identifiée par « nopers » est
plus âgée que la moyenne « moyenne(Affectation * Personne) [NoProjet=noprojet] [DateNaissance] » des
personnes affectées au projet « noprojet » |
Nous allons faire le raisonnement à
partir de l’exemple précédent de la primitive créerAffectation. Il se
généralise aisément aux autres primitives.
L’espace informationnel brut de la primitive créerAffectation
est formé de la seule classe Affectation : à cause de la règle de
l’identifiant, des règles existentielles avec les classes Personne et Projet,
cet espace informationnel concerne aussi les listes suivantes
d’identifiants : IPAffectation, IPPersonne, IPProjet.
A cause de QualifAffect il contient
aussi (Personne * Compétence) [NoPers = nopers] [NoQualif] + (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif] : des objets des classes
Personne, Compétence, Projet, QualifRequise.
A cause de MaxPers, il contient aussi
Affectation [NoProjet=noprojet] : tous les objets de Affectation associés
au projet noprojet.
A cause de +Jeune, il contient aussi
(Affectation * Personne)[NoProjet=noprojet] [DateNaissance] +
Personne[Nopers=nopers] [DateNaissance] : des objets des classes de
Personne.
Ainsi l’espace informationnel réel de la primitive créerAffectation, compte tenu de ce schéma de classes,
n’est plus la seule classe Affectation :
·
il s’étend aux classes Personne,
Compétence, Projet, Qualification ;
·
il s’étend à d’autres objets de
Affectation que le seul objet à créer et à d’autres objets de Personne que le
seul objet concerné.
Cette différence entre l’espace
informationnel brut et réel d’une primitive est importante pour toutes les
questions de concurrence d’accès, de confidentialité et même de distribution.
Ainsi à cause de la règle +Jeune, l’exécution de créerAffectation va devoir
avoir accès aux objets de Personnes impliqués dans le même projet !
Pour diminuer les différences entre les
espaces informationnels bruts et réels des primitives, il faut réexaminer les
classes et leurs attributs en réexaminant les règles autres que les règles de
domaines, d’identifiants, de dépendances existentielles.
Dans l’exemple précédent, nous allons
tenter de diminuer cette différence pour la primitive créerAffectation, par
rapport aux deux règles MaxPers et +Jeune en rajoutant à la classe Projet deux
attributs :
·
MoyDateNaiss : la moyenne des
dates de naissance des personnes affectées au projet.
·
NbPers : le nombre de personnes
affectées à ce projet.
Voici la nouvelle liste de
classes :
Personne (NoPers // DateEmbauche DateNaissance),
Projet (NoProjet // MoyDateNaiss
NbPersProjet Xprojet),
Qualification (NoQualif // Xqualif),
Compétence (NoPers NoQualif // DateAcquisition),
QualifRequise (NoProjet NoQualif // Xqualifrequise),
Affectation (NoPers NoProjet // DateAffectation).
(MoyDN) : pour tout projet sa
moyenne de dates de naissance est égale à la moyenne des dates de naissance des
personnes affectées à ce projet.
" projet Î Projet : projet[MoyDateNaiss] =
moyenne ( (Affectation * Personne)
[NoProjet=projet[NoProjet]] [DateNaissance]).
Cette règle d’intégrité est définie sur
Projet, Affectation, Personne ; c’est un règle ensembliste statique.
(NbPersProjet) : pour tout projet
son nombre de personnes est le nombre de personnes qui lui sont affectées.
" projet Î Projet :
projet[NbPersProjet] = cardinalité
(Affectation[NoProjet=projet[NoProjet]]).
Cette règle d’intégrité est définie sur
Projet, Affectation ; c’est un règle ensembliste statique.
(MaxPers’) : le domaine de
l’attribut NbPersProjet est unentier compris entre 0 et 10.
" projet Î Projet : projet[NbPersProjet] £ 10.
(+Jeune’) : toute nouvelle personne affectée à un projet doit être plus jeune que
la moyenne d’age des personnes déjà affectées à ce projet.
" nouveau
(nopers, noprojet) de Affectation :
Projet
[NoProjet=noprojet] [MoyDateNaiss]) ³
Personne[NoPers=nopers] [DateNaissance].
Dans ce tableau n’apparaît plus la règle MaxPers car elle
n’est plus qu’une règle de domaine.
RI Classes |
Qualif- Affect |
Dembauche |
Dcompé- tence |
+Jeune’ |
MoyDN |
NbPers- Projet |
Personne |
Æ |
Créer,
maj DateNaiss., maj
DateEmb. |
Maj DateEmb. |
Æ |
Maj Date- Naiss. |
Æ |
Projet |
Æ |
Æ |
Æ |
Æ |
Æ |
Æ |
Qualification |
Sup |
Æ |
Æ |
Æ |
Æ |
Æ |
Compétence |
Sup |
Æ |
Créer,
maj DateCompét. |
Æ |
Æ |
Æ |
QualifRequise |
Sup |
Æ |
Æ |
Æ |
Æ |
Æ |
Affectation |
Créer |
Æ |
Æ |
Créer |
Créer, Sup |
Créer, Sup |
créerAffectation (nopers,
noprojet, dateaff) |
ITest |
IRép |
Msg |
IPAff |
IPAffectation |
Ø |
cet identifiant « nopers, noprojet » est déjà
connu |
DEAffPers |
IPPersonne |
Ø |
l’identifiant « nopersonne » est inconnu dans
Personne |
DEAffProj |
IPProjet |
Ø |
l’identifiant « noprojet » est inconnu dans Projet |
DomDateAffectation |
Ø |
Ø |
la valeur « dateaff» n’est pas autorisée pour
l’attribut DateAffectation |
QualifAffect |
(Pers.*Compétence) [NoPers = nopers] [NoQualif] + (Projet *
QualifRequise) [NoProjet = noprojet] [NoQualif] |
(Personne*Compétence) [NoPers = nopers] [NoQualif] + (Projet*QualifRequise) [NoProjet = noprojet] [NoQualif] |
voici les compétences de la personne : (Personne *
Compétence) [NoPers = nopers] [NoQualif] ; voici les qualifications
requises du projet (Projet * QualifRequise) [NoProjet = noprojet]
[NoQualif]. La personne n’a pas assez de compétences dans le domaine du projet |
MaxPers’ |
Ø |
Ø |
le maximum de personnes affectées à un projet est de
10. |
+Jeune’ |
Personne [Nopers=nopers] [DateNaissance] + Projet [NoProjet=noprojet] [MoyDateNaiss.] |
Personne [Nopers=nopers] [DateNaissance] + Projet [NoProjet=noprojet] [MoyDateNaiss.] |
la personne identifiée par « nopers » est
plus âgée « Personne [Nopers=nopers] [DateNaissance] « que la moyenne des personnes affectées au projet
« noprojet » |
MoyDN |
Projet [NoProjet=noprojet] [MoyDateNaiss] + Personne [Nopers=nopers] [DateNaissance] |
Ø |
Ø |
NbPersProjet |
Projet [NoProjet=noprojet] [NbPersProjet] |
Ø |
Ø |
L’espace informationnel brut de la primitive créerAffectation
est toujours formé de la seule classe Affectation : à cause de la règle de
l’identifiant, des règles existentielles avec les classes Personne et Projet,
cet espace informationnel concerne aussi les listes suivantes d’identifiants :
IPAffectation, IPPersonne, IPProjet.
Le nouvel espace informationnel réel de la primitive créerAffectation, compte tenu de ce nouveau schéma de classes
avec ces nouvelles règles, n’est pas la seule classe Affectation :
·
il s’étend aux classes Personne,
Compétence, Projet, Qualification ;
·
mais, il ne s’étend plus à d’autres
objets de Affectation que le seul objet à créer, et à d’autres objets de
Personne que le seul objet concerné de Personne.
Les managers, les ingénieurs, les organisateurs, les
personnes des métiers, les administratifs doivent utiliser quotidiennement
l’informatique, sans être dérangés par elle, l’informatique devant se fondre
dans leurs pratiques quotidiennes, devant leur apporter un soutien efficace
pour affronter leurs situations professionnelles. C’est l’enjeu des systèmes
d’information (SI).
Cet enjeu relève d’une grande complexité dont voici 3
éléments :
- le développement d’un SI conduit à de profonds
changements des pratiques dans une entreprise ;
- il est très difficile (le plus souvent impossible) de prévoir toutes les implications
importantes du développement d’un SI sur une entreprise;
- les SI apportent aux entreprises beaucoup plus que des
solutions à des problèmes.
Ce monde des SI tient compte non seulement du monde de
l’informatique mais aussi du monde des activités de l’entreprise. Son enjeu est celui de leur
interpénétration.
Ce chapitre présente la partie appelée dynamique des SI. Cette partie
s’intéresse aux traitements informatiques des données, aux interfaces entre les
personnes et les traitements informatiques. Elle est souvent considérée comme
la partie essentielle, par ceux qui négligent les schémas informationnels et
les règles d’intégrité. En effet, cette partie est la plus visible et la plus
proche des objectifs à atteindre, de valeur ajoutée apportée par
l’informatique.
La partie dynamique d’un SI est ainsi la plus sensible à
l’enjeu des SI.
Le monde des activités
Ce domaine fait l’objet de cours entiers dans le monde de
la gestion des entreprises. Ce paragraphe en rappelle les concepts importants
pour le développement des SI.
Activités
Les activités humaines constituent la partie vivante de l’entreprise[1] (par
opposition à la partie artificielle, informatisée notamment). Ces activités
peuvent être opérationnelles, de contrôle ou de pilotage. Chaque activité a un
objectif, une mission, une responsabilité ou une fonction à remplir dans un
cadre déterminé. Elle a généralement plusieurs aspects :
un aspect opérationnel composé de tâches à accomplir ;
un aspect réactif qui impose des
réactions face à des événements ;
un aspect décisionnel qui propose un
cadre d’actions pour le futur ;
un aspect de contrôle des actions
faites, en cours ou prévues ;
un aspect de veille concernant
l’évolution de l’environnement de la fonction concernée, autant à l’extérieur
de l’entreprise qu’à l’intérieur de l’entreprise ;
un aspect logistique de flux de
produits ;
un aspect budgétaire et
comptable ;
un aspect de ressources humaines.
Une activité a la responsabilité de ressources qui sont humaines, matérielles, budgétaires… Elle peut
prendre des mesures concernant ces
ressources comme : affecter une
personne à une tâche, décider d’investir un certain budget à l’achat d’un
nouvel équipement, passer un contrat avec un fournisseur…
Organisation
Généralement une institution regroupe des activités de même nature dans une même unité organisationnelle appelée souvent
service, département, subdivision, division, bureau… Souvent une unité se
décompose en plusieurs unités qui dépendent
d’elle.
Une unité a alors plusieurs objectifs, missions,
responsabilités ou fonctions à
assumer. Toutes les activités de l’unité doivent avoir un objectif, mission,
responsabilité ou fonction s’insérant dans le cadre des fonctions assumées par
l’unité.
Une unité a la responsabilité de ressources, notamment de
toutes les ressources de ses activités.
La structure hiérarchique admet habituellement les règles
suivantes :
une unité dépend d’une seule autre
unité supérieure,
chaque unité a un chef,
toute communication entre une unité et
une unité supérieure ou inférieure doit nécessairement passer par son chef et
toute communication directe entre deux unités non dépendantes l’une de l’autre
est interdite.
La structure matricielle remplace la structure
hiérarchique qui est maintenant dépassée depuis l’apparition d’unités transversales
comme le contrôle de gestion, la logistique ou les systèmes d’information. Une
unité est transversale si ses
fonctions demandent des activités qui doivent se coordonner avec des activités
d’autres unités. Ainsi la coordination d’activités d’unités non dépendantes est
devenue nécessaire car l’entreprise doit gérer de plus en plus de transactions
ou de processus qui demandent l’intervention de plusieurs activités d’unités
différentes.
Il s’agit donc pour chaque unité d’organiser ses activités à l’intérieur d’elle-même et de les coordonner selon des protocoles avec
les activités de l’unité dont elle
dépend,
celles des unités qui dépendent d’elle,
et celles des autres unités avec
lesquelles elle communique.
Transaction ou processus
1.1.1. Définition
Une transaction (ou
processus[2]) est une
réaction de l’entreprise à un événement. Elle est prise en charge par une ou plusieurs activités. Une transaction est
atomique si une seule activité la
prend en charge. Généralement une transaction demande une réaction plus
complexe formée par un enchaînement d’activités. La transaction est transversale si les activités la prenant
en charge n’appartiennent pas à une même unité.
1.1.2. Étapes d’une transaction et activités
L’activité originelle
de la transaction la prend en charge au cours de la première étape, en
réagissant à l’événement déclencheur de la transaction : elle en constitue
le dossier formé notamment des
informations sur l’événement déclencheur.
Une transaction se déroule par étapes. Une étape transforme l’état
de la transaction et notamment son dossier : il y a un état initial de l’étape et un état final de l’étape. Chaque étape est prise en charge par une activité qui examine la transaction. À la fin de
chaque étape, une nouvelle activité est sollicitée.
Au cours de la dernière étape, la transaction s’achève
par une dernière activité, son activité finale,
qui rédige le rapport final avec les explications nécessaires et l’expédie aux
unités ou partenaires extérieurs.
Une activité, prenant en charge une transaction au cours
d’une étape, examine son dossier dans
l’état initial de l’étape. Elle peut constater que la transaction n’est pas conforme car elle ne satisfait pas à
certaines conditions : alors l’activité invalide la transaction. Elle peut aussi rejeter une transaction conforme.
Si elle rejette ou invalide une transaction, alors elle
sollicite l’activité prévue par le protocole de la transaction, qui va la
prendre en charge: cette activité peut être l’activité finale de la
transaction.
Sinon elle examine la
transaction en suivant des procédures
établies, en complétant le dossier de la transaction et en prenant les mesures qui s’imposent et qui
s’appliquent aux ressources qui sont sous sa responsabilité.
La transaction s’achève normalement, si toutes les activités sollicitées l’ont acceptée et
examinée. La transaction s’achève prématurément
ou est arrêtée si une ou plusieurs activités sollicitées la rejettent ou
l’invalident.
1.1.3. Contrôle d’une transaction
Une transaction est contrôlée
s’il existe une activité, son activité de
contrôle, qui a comme responsabilité de surveiller son déroulement.
Ce contrôle est fort
si à la fin de chaque étape, c’est cette activité qui prend le contrôle de la
transaction et qui sollicite une nouvelle activité pour l’étape suivante.
Ce contrôle est faible
si cette activité ne fait que surveiller le déroulement de la transaction sans
intervenir dans le choix des activités à solliciter lors de la fin d’une
étape ; ce sont les activités elles-mêmes qui sollicitent les prochaines
activités à la fin de leurs prises en charge de la transaction, ou qui
s’aperçoivent d’elles-mêmes que c’est leur tour de prendre en charge une
transaction.
Une transaction est incontrôlée
s’il n’existe aucune activité de contrôle qui lui soit attribuée.
1.1.4. Représentation d’une transaction
Une transaction est informelle
si son déroulement n’obéit à aucun schéma prévu. Si elle est fortement
contrôlée, c’est son activité de contrôle qui improvise en fonction des
circonstances et du déroulement de la transaction la prochaine étape de la
transaction ainsi que l’activité à solliciter. Si elle est incontrôlée, alors
son déroulement se fait au gré de la reconnaissance de sa situation par les
activités concernées : alors il y a un risque qu’elle soit perdue, c’est-à-dire qu’elle n’atteigne
jamais son terme.
Une transaction est formalisée
si son déroulement suit un modèle qui
indique les différentes étapes du déroulement d’une transaction et pour chacune
d’elles l’activité qui la prend en charge. Les transactions obéissant à un
modèle sont des instances du modèle.
Modèles de transaction
Un modèle demande un langage précis pour le décrire, son méta-modèle (ou même simplement modèle). Nous allons en présenter plusieurs.
1.1.5. Diagramme de séquence
filaire des activités d’une transaction
En voici un
exemple :
-
Diagramme de séquence filaire
d’activités d’une transaction
Ce modèle de la transaction t1 indique que c’est
l’activité ctrl qui prend le contrôle de la transaction au moment de la
survenance de l’événement déclencheur, ainsi qu’au moment de sa fin. Ensuite se
déroulent en séquence les étapes 2, 3, 4, 5, 6, 7 et finalement l’étape finale
8, respectivement prises en charge par les activités 1, 2, 3, 4, 2, 3, ctrl.
A un instant donné, la transaction est soit dans une
étape et prise en charge par l’activité de cette étape, soit dans un état en
train d’attendre d’être prise en charge par l’activité de la prochaine étape.
Une étape a une seule étape qui lui succède et une seule
qui la précède. Seule la première (resp. dernière) étape n’a pas d’étape qui la
précède (resp. succède).
1.1.6. Séquence non filaire et
diagramme d’examen d’une transaction
Considérons le diagramme de séquence précédent
d’activités : on constate que la transaction t1 est prise en charge à deux
reprises par l’activité 2 et par l’activité 3. Rien dans ce modèle ne permet de
savoir si ces activités font le même type d’examen ou non de la transaction.
Voici un premier diagramme d’examen de la transaction t1.
Ce
diagramme est construit à l’aide d’un graphe biparti orienté, formé de deux
types de sommets : les nœuds correspondent à des états de la transaction,
les étoiles aux examens de la transaction, faits au cours des étapes. Ainsi
l’étoile 1 correspond à l’examen fait par la première activité qui prend en
compte l’événement déclencheur de la transaction. L’étoile 8 correspond à
l’examen de la transaction fait par la dernière activité de la transaction.
Les étoiles 3 et 6 sont distinctes : leurs examens
bien qu’ils soient faits par la même activité (activité 2) sont différents. En
fait la transaction est examinée une première fois par l’activité 2 suivant une
certaine procédure et ensuite elle est de nouveau examinée par la même activité
suivant une autre procédure.
Il en est de même des étoiles 4 et 7.
- Diagramme d’examen d’une transaction
Voici un autre diagramme d’examen de la même
transaction :
- Diagramme d’examen de transaction
Dans ce cas, la transaction est examinée suivant la même
procédure par l’activité 2, au cours de la 3ème et de la 6ème
étape. Par contre l’activité 3 fait des examens différents de la transaction au
cours des étapes 4 et 7.
Ainsi avec le diagramme d’examen, on modélise des aspects
plus fins qu’avec le diagramme des séquences puisqu’on différencie les examens
effectués par une même activité.
Par contre cette modélisation conduit à une nouvelle
situation : la transaction examinée par 2 puis par 3/6, doit-elle être examinée
ensuite par 4 ou directement par 7 ? Si les deux sont possibles, alors le
diagramme de séquence précédent doit être modifié :
-
Diagramme de séquence d’activités
d’une transaction
Un tel modèle n’obéit plus aux caractéristiques d’un
diagramme de séquence filaire, car l’étape
Ce diagramme de séquence s’interprète ainsi : si une
étape admet plusieurs étapes successeurs, alors le déroulement de la transaction
en choisit une seule. Ainsi dans l’exemple précédent, la transaction une fois
franchie l’étape 3 sera conduite soit à l’étape 4 soit à l’étape 7 (OU
exclusif).
1.1.7. Diagramme d’examen d’une transaction
Voici un exemple d’un diagramme d’examen d’une autre
transaction t2 :
- Diagramme biparti d’examen d’une transaction
Ce diagramme est formé de deux types de sommets : les
nœuds correspondant aux états de la transaction, les étoiles correspondant aux
examens faits au cours des étapes ; à chaque étoile correspond l’activité
qui pratique l’examen de l’étape.
Ainsi l’activité 1 lors de la 2ème étape
laisse la transaction soit dans l’état qui précède 3, soit dans l’état qui
précède 6, soit dans les deux états. C’est l’examen de l’étape 2 qui indique
laquelle de ces trois situations est la bonne. Dans le cas où l’examen de 2
conduit la transaction dans les 2 états, alors la transaction pourra subir les
examens 3 et 6, ou 4 et 6, ou 5 et 6 « en même temps » : le
déroulement de la transaction n’est plus séquentiel. L’état d’une transaction
peut être complexe, c’est-à-dire formé de plusieurs états.
Examen
Tout examen admettant plusieurs états de base doit avoir
une condition portant sur eux, que la transaction doit vérifier pour qu’il
puisse débuter.
Exemple de condition
de base pour un examen avec 3 états de base :
la transaction est dans ces trois états
(condition ET),
ou bien la transaction est au moins
dans un de ces états (condition OU).
Tout examen admettant plusieurs états comme résultat doit
avoir une condition portant sur eux que la transaction vérifie une fois
l’examen terminé.
Exemple de
condition de résultat pour un examen avec 3 états de résultat :
la transaction est dans ces trois états
après l’examen (condition ET),
ou bien elle est seulement dans un de
ces états (condition OU exclusif).
1.1.8. Diagramme d’activités d’une transaction
Voici le diagramme d’activités de la transaction t2
correspondant au précédent diagramme d’examen de t2 :
-
Diagramme d’activités d’une transaction
1.1.9. Compatibilité d’un diagramme
d’activités et d’un diagramme d’examen d’une même transaction
Soit la
transaction t avec son diagramme d’examen : DEx(Examens, Etats, Base, Rés,
Activités, Charge) et son diagramme d’activités : DAct(Etapes, Succ,
Activités, Charge).
Ces deux diagrammes sont compatibles si
ils ont les mêmes activités ;
il existe une correspondance entre les
examens et les étapes telle que
à une étape
correspond toujours un et un seul examen
et à un examen
correspond au moins une étape :
l’activité
de l’étape est celle qui prend en charge l’examen de cette étape :
pour toute étape et’ qui succède à une étape et,
l’examen ex’ de et’ succède à
l’examen ex de et au travers d’un état eta :
à la première (resp. dernière) étape
correspond un examen dont la base (resp. le
résultat) est le
premier (resp. dernier) état :
1.1.10. Conclusions
Le diagramme d’activités, dont un cas particulier est le
diagramme de séquence, est pratique pour comprendre la circulation du travail
entre les différentes activités et donc entre les différentes unités
organisationnelles de l’entreprise. C’était
un outil conceptuel important des organisateurs.
Le diagramme d’examen est plus riche qu’un simple
diagramme d’activités car, d’une part, il fait apparaître les examens opérés
sur les transactions et, d’autre part, il abandonne le concept d’étape qui devient peu pertinent dans le
cadre de transactions supportées par un système d’information.
Conséquences d’un modèle de transaction
Un modèle dans le domaine des SI sert à concevoir,
développer et faire évoluer le SI. Ainsi un modèle doit susciter des questions
pertinentes aux responsables du SI pour le développement du SI. Pour le modèle
de transaction, voici quelques-unes de ces questions pertinentes dont les
réponses seront comme des conséquences importantes de l’effort de modélisation
des transactions sur le développement du SI.
1.1.11. Global – Local
Voici de nouveau le diagramme d’examen de la transaction
t2 :
-
Diagramme d’examen de la transaction t2
La condition portant sur les résultats de l’examen 2 et
celle portant sur les bases de l’examen 7 ne sont pas indépendantes : si
la condition de 2 portant sur les résultats est un OU exclusif et si celle sur
les bases de 7 est un ET, alors la transaction ne se terminera jamais, l’examen
7 ne pouvant jamais être pratiqué. C’est ainsi que la conception de l’examen 2
ne peut pas être faite totalement indépendamment de celle de 7.
Les autres examens doivent vérifier que, si une base br de l’examen ex’ est un résultat de l’examen ex,
alors la condition de ex’ sur br n’est pas contradictoire avec celle
de ex sur br.
1.1.12. Interférences
Une interférence provient du fait qu’une décision prise
lors d’un examen d’une transaction a des conséquences sur d’autres examens. Nous allons en donner plusieurs types.
La transaction t2 précédente en fournit: elle est
examinée par 2 qui prend une mesure comme celle d’affecter tel véhicule à telle
commande de voyage. Elle est ensuite examinée par 5 qui rejette la transaction
et la transaction s’arrête : que faire de la mesure prise par 2 ? Défaire la mesure, c’est-à-dire
supprimer cette affectation ? Plusieurs questions se posent alors :
n’est-il
pas trop tard ?
s’il est
trop tard, quelle mesure prendre et comment la spécifier dans 8 ?
s’il n’est pas trop tard, il faut la défaire en 8.
De toute façon on s’aperçoit que la conception de 8
demande de connaître les mesures locales des examens de la transaction.
Un autre type d’interférences provient de la prise en
charge de plusieurs instances d’une même transaction ou de transactions
différentes. Un examen de l’une peut conduire à une mesure qui conduit l’autre
à être rejetée par un autre examen.
Par exemple l’examen d’une transaction t1 conduit à
affecter un véhicule à un voyage ; l’examen d’une autre transaction t2
conduit à la même mesure mais il n’y a plus de véhicules disponibles et elle
est rejetée. Il y a interférence car si l’examen de t2 avait été fait avant
celui de t1, ce serait t1 et non t2 qui aurait été arrêtée.
1.1.13. Protocoles entre unités organisationnelles
Le diagramme d’examen d’une transaction indique
clairement des échanges entre les activités et donc entre leurs unités
organisationnelles. Ces diagrammes d’examen des transactions fournissent des
informations pertinentes sur les protocoles d’échanges à mettre sur pied entre
unités organisationnelles comme des départements, des divisions, des
subdivisions, des services.
Le monde de l’informatique
Ce chapitre présente une architecture qui se compose de primitives qui assurent les
manipulations de base : créer, retrouver, supprimer, modifier un objet,
une donnée. Ensuite les opérations définies
sur une classe permettent de faire changer d’état des objets à la demande de responsables de ces objets. Finalement
des traitements font des opérations
complexes sur plusieurs classes. toutes
ces opérations et tous ces traitements doivent valider les règles d’intégrité
définies sur les classes.
Primitives
Ces primitives s’appliquent potentiellement à tous les
objets des classes sauf si les responsables du SI (concepteur, administrateur…)
en ont décidé autrement.
1.1.14. Primitives de base
Voici la liste des primitives de base, applicables à
toute classe C :
·
créer un objet de C,
·
rechercher les objets vérifiant une
condition portant sur leurs valeurs prises pour des attributs de C,
·
modifier les valeurs que prend un objet
de C pour des attributs de C,
·
supprimer un objet de C.
La primitive créer
ne crée un objet de C que si
-
il prend une valeur claire pour tous
les attributs obligatoires[3] de C,
-
pour tout identifiant obligatoire de C,
il prend une valeur qu’aucun autre objet n’a prise avant lui.
Si C est en dépendance existentielle avec C’, la
primitive créer ne crée un objet de C
que s’il est lié à un objet de C’, alors que la primitive supprimer appliquée à un objet de C’ supprime cet objet de C’ avec
tous les objets de C qui lui sont liés.
La primitive modifier
est plus complexe et elle fait l’objet du paragraphe suivant. Néanmoins on
peut facilement constater qu’il est impossible de modifier les valeurs des
objets pour des attributs permanents[4] et en
particulier pour tous les attributs des identifiants permanents d’une classe. D’autre
part les nouvelles valeurs après modification doivent faire partie du domaine
des attributs concernés.
1.1.15.
Les différentes modifications d’objets d’une classe
Toute modification d’un objet concerne le changement de
valeur que prend cet objet o pour un attribut A de sa classe. si A est un attribut permanent, la
modification n’est pas valide.
Il existe trois types de modifications suivant
que :
-
l’attribut A est monovalué[5] ou
multivalué ;
-
le changement concerne une valeur
obscure ou seulement des valeurs claires ;
-
la modification concerne un ou
plusieurs objets.
1.1.16.
Attribut monovalué ou multivalué pour des changements concernant des
valeurs claires
Si l’attribut A est multivalué, alors l’objet o peut
prendre un ensemble de valeurs pour A. Alors la modification des valeurs de o
pour A prend les formes suivantes :
-
mettre v dans A(o) : v doit appartenir au domaine de A ;
le résultat de l’opération est que v
appartient à A(o), que v appartienne
ou non à A(o) avant l’opération ;
o
et pour plusieurs valeurs : mettre v1 v2 v3… dans A(o) ;
-
changer v en v’ dans
A(o) : v doit appartenir à A(o) avant, et v’ doit appartenir au domaine de A ;
-
supprimer v de A(o) : v doit appartenir à A(o) avant, et, dans
le cas où A est obligatoire, A(o) ne doit pas devenir obscur.
Exemple : dans VÉHICULE (oidVéhicule= / NoChâssis=
/ NoVéhicule-= /
NoMoteur // Catégorie=, Marque=, DateCirculation*-) :
·
mettre 28/2/1004 dans
DateCirculation(véh) revient à mettre la date 28/2/1004 dans l’ensemble des
valeurs que prend l’objet véh de la classe VÉHICULE pour l’attribut
DateCirculation : si cette valeur y existait déjà, alors cette opération
ne fait rien.
·
changer 28/2/1004 en 01/03/1004 dans
DateCirculation(véh) revient à changer la date 28/2/1004 dans l’ensemble des
valeurs que prend l’objet véh de la classe VÉHICULE pour l’attribut
DateCirculation, par la date 01/03/1004.
Si A est un attribut monovalué, alors les seules
opérations valides sont :
·
mettre v dans A(o) : v doit appartenir au domaine de A ;
le résultat de l’opération est que v
appartient à A(o), que v appartienne
ou non à A(o) avant l’opération ;
·
changer v en v’ dans
A(o) : v doit appartenir à A(o) avant, et v’ doit appartenir au domaine de A.
1.1.17.
Attribut monovalué ou multivalué pour des changements concernant des
valeurs obscures
Si A est un attribut multivalué alors :
-
clarifier A(o) avec v :
A(o) doit être obscur avant et v
doit appartenir au domaine de A ; le résultat de l’opération est que v appartient à A(o) ;
o
et avec plusieurs valeurs : clarifier
A(o) avec v1 v2 v3… ;
-
obscurcir v dans A(o) : v doit appartenir à A(o) avant, et, dans
le cas où A est obligatoire, A(o) ne doit pas devenir obscur ;
o
et de manière plus générale, obscurcir
A(o) : A(o) devient obscur et cette opération est valide seulement si A
n’est pas un attribut obligatoire.
Exemple : dans VÉHICULE (oidVéhicule= / NoChâssis=
/ NoVéhicule-= /
NoMoteur // Catégorie=, Marque=, DateCirculation*-) :
-
obscurcir 28/02/1004 dans
DateCirculation(véh) revient à obscurcir la date 28/2/1004 dans l’ensemble des
valeurs que prend l’objet véh de la classe VÉHICULE pour l’attribut
DateCirculation ;
-
obscurcir DateCirculation(véh) revient
à obscurcir toutes les dates de l’ensemble des valeurs que prend l’objet véh de
la classe VÉHICULE pour l’attribut DateCirculation ;
-
clarifier DateCirculation(véh) avec
28/02/3004 revient à mettre 28/02/3004 dans l’ensemble des valeurs de
DateCirculation(véh) qui était obscur auparavant.
Si A est monovalué alors :
-
clarifier A(o) avec v :
A(o) doit être obscur avant et v
doit appartenir au domaine de A ; le résultat de l’opération est que v appartient à A(o) ;
-
obscurcir A(o) : A(o) devient
obscur et cette opération est valide seulement si A n’est pas un attribut
obligatoire.
Remarque : on peut tolérer que l’opération
précédente mettre puisse avoir comme
sens particulier clarifier ;
dans ce cas, la valeur avant l’opération peut être obscure.
1.1.18.
Modification au singulier ou au pluriel
Les opérations précédentes concernent des modifications
d’un objet (modification au singulier).
Une modification de plusieurs objets par une seule
opération (modification au pluriel)
n’est pas équivalente à l’exécution successive de modifications au singulier,
du point de vue des performances. En effet, la validation des règles
d’intégrité donne lieu à des algorithmes généralement plus performants quand on
les applique à un ensemble d’objets, que quand on les applique plusieurs fois à
un seul objet.
Notation : les noms des opérations de modification
au pluriel commencent par une lettre majuscule, celles au singulier par une
minuscule.
Voici les opérations au
pluriel, définies sur un attribut multivalué :
-
Mettre v dans A(o1), A(o2), A(o3) … : , v doit appartenir au domaine de A ; comme résultat de
l’opération, v appartient à A(o1),
A(o2), A(o3) …, que v appartienne
ou non à l’un des A(o) avant l’opération ;
o
pour plusieurs valeurs : Mettre v1 v2 v3… dans A(o1), A(o2),
A(o3) …;
-
Changer v en v’ dans A(o1),
A(o2), A(o3) … : , v doit
appartenir à A(o) avant, sinon l’opération ne modifie pas A(o) ; de plus v’ doit appartenir au domaine de
A ;
-
Supprimer v de A(o1), A(o2), A(o3) …: , v doit appartenir à A(o) avant (sinon aucun effet), et, dans le cas
où A est obligatoire, aucun A(o) ne doit devenir obscur.
Si A est un attribut monovalué, alors les seules
opérations valides sont :
-
Mettre v dans A(o1), A(o2),
A(o3) … : , v doit appartenir au domaine de A ; comme résultat de
l’opération, v appartient à A(o1), A(o2), A(o3) …, que v appartienne ou
non à A(o1), A(o2), A(o3) … avant l’opération ;
-
Changer v en v’ dans A(o1), A(o2),
A(o3) … : , v doit appartenir à A(o1), A(o2), A(o3) … avant, et v’
doit appartenir au domaine de A ;
1.1.19.
Attribut monovalué ou multivalué avec des valeurs obscures
Si A est un attribut multivalué alors :
-
Clarifier A(o1), A(o2), A(o3) …
avec v : les A(o) doivent être obscurs
avant et v doit appartenir au domaine de A ; comme résultat de
l’opération, v appartient à A(o1), A(o2), A(o3) … ;
o
et avec plusieurs valeurs, Clarifier
A(o1), A(o2), A(o3) … avec v1 v2 v3… : les A(o) doivent être obscurs avant, et les
v1 v2 v3… doivent appartenir au domaine de A ; comme résultat de
l’opération, les v1 v2 v3… appartiennent à A(o1), A(o2), A(o3) … ;
-
Obscurcir v dans A(o1), A(o2),
A(o3) …: si v appartient à un des A(o) avant, alors il est remplacé par la
valeur obscure, et, dans le cas où A est obligatoire, A(o) ne doit pas devenir
obscur ;
-
et, de manière plus générale, Obscurcir
A(o1), A(o2), A(o3) …: alors les A(o) deviennent obscurs et cette
opération est valide seulement si A n’est pas un attribut obligatoire.
Si A est monovalué alors :
-
Clarifier A(o1), A(o2), A(o3) …
avec v : les A(o1), A(o2), A(o3) …
doivent être obscurs avant et v doit appartenir au domaine de A ; comme
résultat de l’opération, v appartient aux A(o1), A(o2), A(o3) …
-
Obscurcir A(o1), A(o2), A(o3) … :
les A(o1), A(o2), A(o3) … deviennent obscurs et cette opération est valide
seulement si A n’est pas un attribut obligatoire.
1.1.20.
Exemple de primitives de modification d’objets d’une classe
Voici l’ensemble des primitives de la classe VÉHICULE
(oidVéhicule= / NoChâssis= / NoVéhicule-= / NoMoteur // Catégorie=, Marque=,
DateCirculation*-).
·
oidVéhicule=, NoChâssis= :
aucune modification possible de ces attributs, car ils font partie
d’identifiants obligatoires.
·
NoVéhicule-= : clarifier et Clarifier sont les
seules primitives de modification autorisées car c’est un attribut permanent
admettant la valeur obscure.
·
NoMoteur : les primitives
concernant un attribut monovalué, clarifier, mettre, obscurcir, changer, Clarifier,
Mettre, Obscurcir sont autorisées, mais leur exécution doit vérifier que
NoMoteur est un identifiant de la classe VÉHICULE.
·
Catégorie=,
Marque= : aucune modification
possible de ces attributs car ce sont des attributs permanents et obligatoires.
·
DateCirculation*- : comme
c’est un attribut multivalué et admettant les valeurs obscures, toutes les
primitives de modifications sont autorisées sur cet attribut.
Cycle
de vie primitif de tout objet
Dans le processus de modélisation, il est recommandé de
considérer trois autres primitives de base : activer, désactiver et
faire renaître des objets de la
classe.
Le cycle de vie primitif de tout objet o est la séquence
suivante d’exécution :
-
créer(o) activer(o) désactiver(o)
supprimer(o), avec une variante :
-
créer(o) activer(o) désactiver(o)
renaître(o) activer(o) désactiver(o) supprimer(o).
Entre créer(o) et activer(o) :
-
l’objet o peut ne pas vérifier les
règles d’intégrité définies sur sa classe ;
-
il ne peut être associé à aucun autre
objet, excepté les objets dont il dépend existentiellement ou les objets qui
dépendent de lui existentiellement ;
-
il ne peut être atteint par aucune
opération, excepté activer(o) ou supprimer(o).
La primitive activer(o) n’est valide que si o valide
toutes les règles d’intégrité définies sur sa classe ; alors l’objet peut
être associé à d’autres objets et être atteint par les opérations définies sur
sa classe ; tous les objets dont o dépend existentiellement, doivent être
actifs.
La primitive désactiver(o) rend l’objet inatteignable aux
opérations de sa classe, excepté supprimer (o) et renaître (o) ; l’objet o
conserve ses valeurs identifiantes pour les identifiants obligatoires de sa
classe ; tous les objets dépendant existentiellement de o sont également
désactivés.
La primitive supprimer(o) supprime l’objet o et toute
trace de sa présence avec en particulier ses valeurs identifiantes ; tous
les objets dépendant existentiellement de o sont également supprimés.
La primitive renaître(o) prépare l’objet o à être de
nouveau actif. L’objet o passe dans l’état recréé ; tous les objets dont o
dépend existentiellement, doivent être dans l’état recréé ou actif.
Voici le cycle de vie générique de tout objet de toute
classe :
-
Cycle de vie primitif de tout objet
Ce cycle est représenté à l’aide d’un réseau de nœuds et
d’étoiles : les nœuds correspondent à des états, les étoiles aux
primitives. L’étoile 1 correspond à la primitive créer, 2 à la primitive activer,
0 aux opérations de la classe qui peuvent atteindre l’objet, 3 à la primitive désactiver, 4 à la primitive supprimer, 5 à la primitive renaître.
Etat, opération, traitement
1.1.21. Etat
Les états associés à une classe sont des
propriétés pour lesquelles les objets de C vont prendre des valeurs et ces
valeurs vont définir l’état de l’objet. De plus, en règle générale, ces valeurs
ne peuvent être modifiées que par des opérations.
Le plus souvent, un état est de même nature
qu’une classe :
-
les objets dans un état
sont bien sûr des objets de C : ils en ont les propriétés, mais certaines
de ces propriétés peuvent être inhibées à cause du fait que l’objet est dans
cet état ; ainsi un véhicule en
panne ne peut plus être affecté à une ligne.
-
les objets dans un état
peuvent avoir des propriétés propres à cet état : pour un véhicule en réparation il est possible de changer
son moteur, d’indiquer le temps prévu de réparation, la date de fin de sa
réparation.
-
les objets dans un état
sont concernés par des règles d’intégrité propres à cet état : ainsi un
véhicule en service ne peut être
affecté qu’à une ligne de même catégorie que lui (un tramway à une ligne de
tramway, un trolleybus à une ligne de trolleybus…).
1.1.22. Opération
Une opération est définie sur une classe C à l’aide d’une
spécification algorithmique : cette classe est appelée la classe de
définition de l’opération. Lors de son exécution, elle atteint un ou plusieurs
objets de C, ses objets de base, à
partir desquels elle en tire des conséquences soit en modifiant des valeurs
d’objets de base, soit en créant des objets, en activant ou désactivant
d’autres ou bien en changeant les états d’objets de base. Ses conséquences sont
réalisées à l’aide des primitives et des opérations définies sur C.
Sa spécification
algorithmique comprend :
-
la signature
de l’opération désigne l’ensemble des opérations qu’elle utilise ;
-
la signature
développée de l’opération désigne l’ensemble des primitives utilisées par
elle-même et par les opérations qu’elle utilise.
Remarque : une
opération ne peut pas directement agir sur des objets des classes : elle
doit utiliser les primitives de base. Elle ne peut pas utiliser les primitives
de renaître et de supprimer qui sont réservées à l’administration du SI.
Toute opération a potentiellement deux versions, l’une au
singulier, l’autre au pluriel.
La déclaration d’une opération comprend les parties
suivantes :
-
son nom qui permet de l’identifier
parmi toutes les opérations ;
-
une explication de ses principes ;
-
sa
classe de définition ;
-
ses états de base : les objets de
base de toute exécution sont dans l’un de ces états;
-
ses conséquences : ce sont les
classes ou les états dans lesquels se retrouvent les conséquences d’une
exécution ;
-
sa
spécification algorithmique ;
-
sa condition de base qui porte sur les
objets de base ;
-
sa condition de conséquence qui porte
sur les conséquences ;
-
sa
signature.
Exemple : VÉHICULE (oidVéhicule= / NoChâssis=
/ NoVéhicule-= /
NoMoteur // Catégorie=, Marque=, DateCirculation*-).
Voici des opérations de la classe VÉHICULE :
·
opération immatriculer
(véhicule : Véhicule) : l’objet avec une valeur obscure pour l’attribut
NoVéhicule, prend maintenant une valeur claire, qui ne doit être utilisée par
aucun autre objet de Véhicule. Sa conséquence est de rendre actif
l’objet véhicule.
·
opération changermoteur
(véhicule : Véhicule) : l’objet va changer de valeur pour l’attribut
Moteur ; il prend une nouvelle valeur claire qui ne doit être utilisée par
aucun autre objet de Véhicule.
·
opération contrôler (véhicule : Véhicule).
·
opération
réparer (véhicule : Véhicule).
L’opération contrôler
s’applique à un objet o d’un véhicule
soumis à un contrôle technique. Sa conséquence est que l’objet o se trouve dans l’état disponible.
L’opération réparer
s’applique à un objet o d’un véhicule
soumis à une réparation. Sa conséquence est que l’objet o se trouve dans l’état disponible.
La signature de contrôler
contient réparer. Celle de réparer contient changermoteur. La
signature développée de contrôler contient
changermoteur.
1.1.23. Traitement
Un traitement est défini sur plusieurs classes Ck de
définition à l’aide d’une spécification algorithmique. Lors de son exécution,
il atteint un ou plusieurs objets des Ck, ses objets de base, à partir desquels il en tire des conséquences soit
en modifiant des valeurs des objets de base, soit en créant des objets, en
activant ou désactivant d’autres ou bien en changeant les états d’objets de
base.
Les conséquences d’un traitement sont des classes qui
sont en dépendance existentielle avec des classes qui sont des bases du
traitement, à moins qu’elles ne soient en dépendance existentielle avec aucune
autre classe.
Sa spécification algorithmique utilise les opérations et
primitives définies sur les Ck :
-
la signature
du traitement désigne l’ensemble des opérations qu’il utilise ;
-
la signature
développée du traitement désigne l’ensemble des primitives utilisées par
lui-même et par les opérations des Ck qu’il utilise.
Remarques : une
opération est un cas particulier d’un traitement.
Comme les
opérations, un traitement n’agit pas directement sur des objets des
classes : il doit utiliser les primitives de base. Il ne peut utiliser les
primitives de renaître et de supprimer.
Tout traitement est susceptible d’avoir deux versions,
l’une au singulier et l’autre au pluriel.
La déclaration d’un traitement comprend les parties
suivantes :
-
son nom qui permet de l’identifier
parmi toutes les opérations et tous les traitements ;
-
une explication de ses principes ;
-
ses
classes de définition ;
-
ses bases : ce sont les classes ou les
états dans lesquels se trouvent ses objets de base de toute exécution ;
-
ses conséquences : ce sont les
classes ou les états dans lesquels se retrouvent les conséquences d’une
exécution ;
-
sa
spécification algorithmique ;
-
sa condition de base qui porte sur les
objets de base ;
-
sa condition de conséquence qui porte
sur les conséquences ;
-
sa
signature.
Notation : si t désigne un traitement alors
-
C(t) désigne l’ensemble des classes de
définition de t ;
-
°t et t° sont respectivement ses bases
et ses conséquences ;
-
base(t) et conséquence(t) sont ses
conditions respectives de base et de conséquence ;
-
signature(t) et signature*(t) sont
respectivement sa signature et sa signature développée.
Caractéristique des
traitements
Tout traitement admet au moins une base et
une conséquence.
Exemple :
LIGNE (CodeLigne
// Catégorie TypeLigne ArrêtDépart ArrêtArrivée)
AFF-VEHICULE (NoVéhicule DateAff //
StatutVéhicule CodeLigne StatutAffectation).
Le traitement affectation-véhicule affecte un véhicule
disponible à une ligne à une date donnée. Les classes de définition sont LIGNE
et AFF-VEHICULE. Les objets de AFF-VEHICULE doivent être dans l’état disponible. Ses conséquences sont des
objets de AFF-VEHICULE dans l’état affecté.
Sa signature contient clarifier AFF-VEHICULE.CodeLigne, changer
AFF-VEHICULE.StatutVéhicule, changer AFF-VEHICULE.StatutAffectation.
-
Schéma
du traitement affecter un véhicule
On peut
juxtaposer les schémas de données et de traitements :
-
Schéma de données et de traitements
1.1.24. Schéma de traitements
Un schéma de traitements se construit simplement à l’aide
d’un graphe biparti orienté, formé de deux types de sommets : les nœuds
correspondent à des classes, les étoiles aux traitements. Le nœud d’une classe
C est relié à l’étoile du traitement t si C est une base de t. L’étoile du
traitement t est relié au nœud de la classe CC si CC est une conséquence de t.
Le monde de
l’information et de la communication
Enjeux
Au début de l’informatisation, les traitements étaient
des robots : on lançait leur
exécution qui remplissait un certain nombre de tâches roboratives avec beaucoup
plus de rapidité, sécurité, fiabilité que ne pouvaient le faire des personnes. Un
robot ne tombe jamais malade, ne se trompe jamais, n’est jamais fatigué,
calcule toujours juste. Ainsi il y eut les grandes applications informatiques de gestion comme le calcul de la paie,
le traitement des commandes, les applications comptables. Mais un robot
n’exécute que les opérations de son programme.
-
Rapidement ces applications sont apparues très compliquées car elles devaient
prendre en compte tout un ensemble de paramètres, de cas particuliers qui
ralentissaient et compliquaient considérablement les travaux d’analyse, de
développements informatiques et de tests de fiabilité.
-
De plus, ces applications sont apparues très rigides, car toutes ces
complications rendaient leur maintenance rapidement très compliquée :
ainsi devoir modifier une règle de
gestion comme un taux de remise ou un taux de primes, ou bien rajouter des
conditions pour l’obtention de primes pouvait être pratiquement
impossible !
L’ingénierie des
systèmes d’information
-
ouvre ces applications informatiques en les considérant comme
étant formées de composants doués d’une certaine autonomie autant dans leur
conception que dans leur réalisation informatique ;
-
met au centre de l’analyse et du
développement informatique, l’utilité du système d’information à aider
efficacement les personnes qui vont travailler avec lui.
Ces personnes doivent avoir un véritable poste de travail
informationnel avec
-
des informations dont elles ont besoin
pour assurer les responsabilités, leurs tâches,
-
des opérations qu’elles peuvent
déclencher pour faire face aux événements : l’exécution de ces opérations
va prévenir d’autres personnes, modifier des informations ou proposer des
conduites d’action ;
-
des possibilités de contrôler
l’exécution de traitements, d’intervenir sur leur déroulement, y compris de les
arrêter.
Examen et traitement
Entre le modèle de transaction avec son diagramme
d’examen et le modèle de traitement avec son schéma, il faut construire
solidement un nouveau schéma dont le concept central est un mélange d’examen et
de traitement. Il s’agit de savoir comment :
aider efficacement un examen humain par un traitement
informatique, voire même le remplacer ?
reconstruire des examens à partir d’un schéma de
comportement, et par voie de conséquences comment redéfinir des activités et
même des protocoles de coordination entre unités organisationnelles ?
construire des interfaces cognitives pour les examens qui
sont supportés par des traitements ? Ces interfaces cognitives doivent
fournir toutes les informations utiles aux personnes conduisant l’examen.
La difficulté de cette approche provient
du décalage
entre un examen d’une transaction et un traitement : tout examen n’est
pas informatisable ou bien il ne peut
l’être que partiellement ou bien il
peut l’être totalement ;
de la place du SI, s’il est en prise directe avec les affaires comme dans
le cas de la réservation de billets d’avion, ou s’il est en périphérie comme
dans le cas de la décision d’annulation d’un vol ;
de la dualité entre examen et traitement : lequel des deux se
définit-il par rapport à l’autre ? faut-il d’abord déterminer les examens
et ensuite en déduire les traitements ou l’inverse ? Il n’y a pas de règle
absolue et les responsables de développement de SI doivent s’attendre à faire les
deux et à être capable de mener une étude complète et correcte en considérant
tantôt un examen tantôt un traitement comme élément de base de
développement ;
de la durabilité des activités : certaines activités concernent des
métiers ou des responsabilités durables,
c’est-à-dire dont la raison d’être
n’est pas remise en question par le développement du SI ; par contre
d’autres, plus liées à l’organisation de l’entreprise ou aux relations entre
l’entreprise et son environnement (clients, fournisseurs…), sont susceptibles
d’être transformées, y compris dans leurs objectifs, missions, responsabilités
ou fonctions, par le développement du SI.
Au début de
l’informatisation, les traitements étaient des robots : on lançait leur exécution qui remplissait
un certain nombre de tâches roboratives avec beaucoup plus de rapidité,
sécurité, fiabilité que ne pouvaient le faire des personnes. Un robot ne tombe
jamais malade, ne se trompe jamais, n’est jamais fatigué, calcule toujours
juste. Ainsi il y eut les grandes applications
informatiques de gestion comme le calcul de la paie, le traitement des
commandes, les applications comptables. Mais un robot n’exécute que les
opérations de son programme.
-
Rapidement ces applications sont
apparues très compliquées car elles devaient prendre en compte tout un ensemble
de paramètres, de cas particuliers qui ralentissaient et compliquaient
considérablement les travaux d’analyse, de développements informatiques et de
tests de fiabilité.
-
De plus, ces applications sont
apparues très rigides, car toutes ces complications rendaient leur maintenance
rapidement très compliquée : ainsi devoir modifier une règle de gestion comme un taux de remise ou un taux de
primes, ou bien rajouter des conditions pour l’obtention de primes pouvait
être pratiquement impossible !
L’ingénierie des
systèmes d’information
-
ouvre ces applications informatiques en les
considérant comme étant formées de composants doués d’une certaine autonomie
autant dans leur conception que dans leur réalisation informatique ;
-
met au centre de l’analyse et du développement informatique, l’utilité du
système d’information à aider efficacement les personnes qui vont travailler
avec lui.
Ces personnes
doivent avoir un véritable poste de travail informationnel avec
-
des informations dont elles ont besoin pour assurer les responsabilités,
leurs tâches,
-
des opérations qu’elles peuvent déclencher pour faire face aux
événements : l’exécution de ces opérations va prévenir d’autres personnes,
modifier des informations ou proposer des conduites d’action ;
-
des possibilités de contrôler l’exécution de traitements, d’intervenir sur
leur déroulement, y compris de les arrêter.
Entre le modèle
de transaction avec son diagramme d’examen et le modèle de traitement avec son
schéma, il faut construire solidement un nouveau schéma dont le concept central
est un mélange d’examen et de traitement. Il s’agit de
savoir comment :
aider
efficacement un examen humain par un traitement informatique, voire même le
remplacer ?
reconstruire des
examens à partir d’un schéma de comportement, et par voie de conséquences
comment redéfinir des activités et même des protocoles de coordination entre
zones de responsabilité ?
construire des
interfaces cognitives pour les examens qui sont aidés par des
traitements ? Ces interfaces cognitives doivent fournir toutes les
informations utiles aux personnes conduisant l’examen.
La difficulté de
cette approche provient
d’une part, du décalage entre un examen d’une transaction et un
traitement : tout examen n’est pas informatisable
ou bien il peut l’être que partiellement
ou bien il peut l’être totalement,
d’autre part, de la dualité entre examen et traitement : lequel des
deux se définit-il par rapport à l’autre ? faut-il d’abord déterminer les
examens et ensuite en déduire les traitements ou l’inverse ? À notre
connaissance, il n’y a pas de règle absolue et les responsables de
développement de SI doivent s’attendre à faire les deux et à être capable de
mener une étude complète et correcte en considérant tantôt un examen tantôt un
traitement comme élément de base de développement.
Un système d’information est un carrefour informationnel de nombreuses
activités. Les différents modèles reflètent de la manière la plus rigoureuse
les informations prises en compte, les choix d’implémentation relatifs aux
informations, les pratiques informatisées en termes de traitement, les règles
d’intégrité correspondant pour la plupart à des règles de gestion des activités.
Le modèle du système d’information composé de tous ces modèles, est un
outil pour développer le système d’information autant au niveau informatique
qu’au niveau organisationnel. Il est donc indispensable de bien comprendre un
modèle de système d’information si l’on veut être un acteur conséquent de son
développement.
D’autre part, un système d’information est aussi un carrefour d’enjeux
professionnels pour toutes les activités concernées. Ce sont de nombreuses
visions ou demandes qui peuvent surgir et qui ne peuvent être poursuivies ou
satisfaites toutes. Il faut organiser des négociations. Le modèle de système
d’information offre alors un cadre de négociation car il permet de replacer
visions et demandes dans la perspective du développement du système d’information.
Il permet également d’accorder la politique de développement du système
d’information avec celles de l’entreprise. Aussi devient-il impérieux que les
personnes assises à la table des négociations aient la compétence de lire et de
comprendre tous les modèles composant un modèle de système d’information.
En particulier, il nous semble essentiel de ne pas confondre les deux
mondes, celui des activités humaines et celui des pratiques informatisées. Il
ne s’agit pas de faire un modèle d’activités et de le traduire en un modèle de
pratiques informatisées, ou bien, inversement, de traduire un modèle de
pratiques informatisées en un modèle d’activités. Les liens entre ces modèles
sont beaucoup plus riches et le concept de décalage s’impose. C’est une des
connaissances fondamentales du monde des systèmes d’information à notre avis.
Ainsi si les acteurs d’un système d’information ont l’impression que le système
d’information s’est fondu dans leurs activités, ce résultat provient seulement
du talent et des compétences de l’équipe de développement du système
d’information, qui a notamment su maîtriser les décalages entre activités et
pratiques informatisées.
Bien au-delà de simplement construire un pont entre le monde des activités
et le monde de l’informatique, le monde des systèmes d’information est un
domaine en lui-même, qui a sa propre rigueur, ses propres règles et concepts.
Ce livre en a présenté les bases.
Le monde des systèmes d’information fournit continuellement des directions
prometteuses pour le développement du monde des activités et celui de
l’informatique. Ainsi toute personne compétente en système d’information peut
aussi tenir un rôle pertinent dans le développement de l’un de ces mondes.
SUJET : GESTION DE
COMMANDES (GESTCDE)
On s’intéresse à la gestion des
commandes d’une société. Les commandes portent sur des produits qui sont
identifiés par un numéro. Chaque produit se décrit à l’aide d’un libellé et est
associé à un prix unitaire. Des clients dont on connaît le numéro, le nom, le
prénom et l’adresse, commandent de ces produits. Chaque commande contient des
informations générales telles que le client qui passe commande, la date, le
total ou l’adresse de livraison de la commande. Elle se constitue d’un certain
nombre de lignes de commande qui correspondent chacune à un produit et à la
quantité commandée de ce produit.
Dans la base de
données de l’entreprise, on gère aussi la livraison des commandes. Une
livraison doit s’effectuer dans les 15 jours suivant la commande. Elle
correspond nécessairement à une commande et aux produits de cette
commande. Pour une livraison donnée,
pour une commande donnée, on enregistre la quantité des produits livrés.
Si les produits
livrés sont défectueux ou ne répondent pas aux besoins du client, ils peuvent
être retournés à l’entreprise.
PRODUIT (NumProd, LibelléProd, PrixUnitaireProd)
<np, l, p> Î PRODUIT Û le produit
de numéro np a pour libellé l et pour prix unitaire p.
CLIENT (NumClient // Nom, Prénom, AdresseClient)
<cl, n, p, a> Î CLIENT Û le client
de numéro cl a pour nom n, pour prénom p et habite à
l'adresse a.
COMMANDE
(NumCde // NumClient, DateCde, Total, AdresseLivraison)
<nc,cl,d,t,a> Î COMMANDE Û la commande
de numéro nc a été passée par le client cl à la date d,
pour un total de t francs. Cette commande est pour l'adresse a.
LIGNECDE (NumCde,
NumProd, QuantiteProdCde)
<nc,np,q> Î LIGNECDE Û la commande
nc comporte une ligne portant sur le produit np pour une quantité
q.
LIVRCDE (NumLiv
NumCde // DateLivr, EtatLivr)
<nl,nc,d,e> Î LIVRCDE Û la
livraison nl porte sur la commande nc et a lieu à la date d.
Elle est dans l’état e (Acceptée ou Refusée).
LIVRCDEPRODUIT (NumLiv, NumCde, NumProd, QteLivrée)
<nl,nc,np, q> Î LIVRCDEPRODUIT Û la
livraison nl de la commande nc comporte q quantité du
produit np.
RENVOI(NumLiv, NumCde, DateRenvoi)
<nl,nc,d> Î RENVOI Û la livraison nl portant sur la
commande nc a été renvoyée à la date d.
1.
Trouver le ou les
identifiants des relations : PRODUIT, LIGNECDE, LIVRCDEPRODUIT, RENVOI.
2.
Répondre aux questions
suivantes en justifiant votre réponse :
a)
Peut-on livrer une commande
en plusieurs fois ?
b)
Une livraison
concerne-t-elle une seule commande ?
c)
Une livraison
concerne-t-elle un seul client ?
d)
Une livraison peut-elle
concerner un seul produit ?
e)
Peut-on livrer les quantités d’un même produit d’une
même commande en plusieurs fois ?
f)
Peut-on livrer plusieurs
commandes en une seule livraison (un seul numéro de livraison)?
g)
Les livraisons d’une
commande doivent-elles amener les produits à la même adresse ?
h)
L’adresse de livraison
d’une commande doit-elle être identique à l’adresse du client?
i)
Dans une livraison il y a
des articles d’un produit qui sont défectueux.
Peut-on simplement les renvoyer et laisser les articles conformes du
même produit de cette livraison chez le client?
j)
Dans une livraison il y a
des articles d’un produit qui sont défectueux. Par contre les articles des
autres produits livrés en même temps sont tous conformes à la commande. Si l’on
retourne les articles du produit dont certains sont défectueux, peut-on laisser
les articles des autres produits chez le client ?
k) Une fois la livraison effectuée peut-on mettre-à-jour la quantité livrée de
produits chez un client ?
1.
Afficher tous les renseignements concernant les clients.
2.
Afficher tous les noms des clients.
3.
Afficher tous les noms et prénoms des clients.
4.
Afficher tous les numéros des clients qui ont passé des commandes.
(Chaque numéro du client sera affiché une seule
fois)
5.
Afficher tous les renseignements concernant les clients par ordre
alphabétique.
6.
Triez les commandes selon l’ordre croissant de leurs totaux.
7.
Affichez tous les renseignements concernant le client no 2.
8.
Affichez tous les renseignements concernant le client dont le nom commence
par ‘L’.
9.
Sélectionnez toutes les commandes dont le total de la commande est
supérieur à 1000 par ordre croissant.
10. Donnez les numéros des
commandes, les numéros des clients, les dates des commandes et les totaux des
commandes pour lesquels le total est entre 800 et 1000 par ordre chronologique.
11. Donnez les renseignements
concernant les commandes pour lesquelles le total est supérieur à 1000 ou
inférieur à 100.
12. Donnez les numéros des
commandes, les numéros des clients, les dates des commandes et les totaux des
commandes pour lesquels le total n’est pas supérieur à 100.
13. Donnez les noms, prénoms des
clients qui n’ont pas d’adresse.
14. Donnez les renseignements
concernant les livraisons datées avant le 01.01.2000 et son état est ‘Refusée’.
15. Donnez les numéros des
livraisons et leurs dates, concernant la commande ‘10’ et dont l’état n’est pas
‘Accepté’.
16. Donnez les renseignements
concernant les commandes datées après le 31.12.1999 et son total est entre 100
et 5000.
17. Quel est le total moyen des
commandes passées après le 01.01.2001 et avant 30.06.2001 ?
18. Affichez la quantité, les
totaux maximum et minimum des commandes de l’année 2000.
19. Quel est le total moyen des
commandes effectuées par un client ?
20. Affichez les clients qui ont
passé des commandes dont la moyenne des totaux est supérieure à 1000.
1.
Créez les tables et spécifiez leurs contraintes d’identifiant pour les
relations PRODUIT, CLIENT, COMMANDE, LIGNECDE, LIVRCDE, LIVRCDEPRODUIT, RENVOI.
2.
Insérez des tuples dans les relations ci-dessus en spécifiant les valeurs à
insérer comme suit :
PRODUIT
NumProd |
LibelléProd |
PrixUnitaireProd |
111 |
Notebook |
3000 |
112 |
Imprimante |
500 |
113 |
Scanner |
200 |
CLIENT
NumClient |
Nom |
Prénom |
AdresseClient |
1 |
MENU |
NILOLAS |
Général Dufour, 24 |
2 |
LEE |
ROBERTO |
Miremont, 46 |
3 |
BLOND |
ALEXANDRE |
Rue de Lausanne, 01 |
COMMANDE
NumCde |
NumClient |
DateCde |
Total |
AdresseLivraison |
10 |
1 |
15.12.99 |
32.500 |
Général Dufour, 24 |
20 |
2 |
20.01.00 |
24.000 |
Rue de Lyon, 03 |
30 |
1 |
18.06.00 |
2.500 |
Miremont, 29 |
40 |
3 |
20.09.00 |
6.000 |
Rue de Lausanne, 01 |
50 |
1 |
30.12.00 |
1.600 |
Général Dufour, 24 |
60 |
2 |
07.01.01 |
3.100 |
Rue de Genève, 120 |
LIGNECDE
NumCde |
NumProd |
QuantiteProdCde |
10 |
111 |
10 |
10 |
112 |
5 |
20 |
111 |
8 |
30 |
112 |
5 |
40 |
111 |
2 |
50 |
113 |
8 |
60 |
112 |
5 |
60 |
113 |
3 |
LIVRCDE
NumLiv |
NumCde |
DateLivr |
EtatLivr |
901 |
10 |
25.01.00 |
Accepté |
901 |
20 |
25.01.00 |
Accepté |
902 |
30 |
30.06.00 |
Accepté |
903 |
40 |
30.09.00 |
Refusée |
904 |
50 |
02.01.01 |
Accepté |
904 |
60 |
10.01.01 |
Accepté |
LIVRCDEPRODUIT
NumLiv |
NumCde |
NumProd |
QteLivrée |
901 |
10 |
111 |
10 |
901 |
10 |
112 |
5 |
901 |
20 |
111 |
8 |
902 |
30 |
112 |
5 |
903 |
40 |
111 |
0 |
904 |
50 |
113 |
8 |
904 |
60 |
112 |
5 |
904 |
60 |
113 |
3 |
RENVOI
NumLiv |
NumCde |
DateRenvoi |
903 |
40 |
30.09.00 |
3.
Affichez tous les numéros, libellés, prix unitaires des produits
qui correspondent à la commande 10.
4.
Affichez tous les noms, prénoms, adresses des clients qui effectuent des
commandes datées après le 31.12.99.
5.
Affichez tous les noms, prénoms des clients qui effectuent les commandes
datées pendant l’année 2000 et son total est entre 1000 et 5000.
6.
Affichez tous les numéros des commandes, dates des livraisons, numéros des
clients, noms des clients, prénoms des clients concernant les livraisons pour
la commande 10.
7.
Affichez tous les numéros des clients, noms des clients, prénoms des
clients, numéros des commandes, dates des livraisons concernant les livraisons
pour la commande 30 et dont l’état de la livraison n’est pas ‘Accepté’.
8.
Affichez tous les noms, prénoms des clients qui effectuent les commandes
pour lesquels le total moyen est supérieur à 10000.
9.
Affichez tous les noms, prénoms, adresses des clients qui ont effectué le
produit 112 pendant l’année 2000.
10. Donnez la liste de toutes
les commandes (incluant les numéros des commandes, numéros des clients, noms
des clients, prénoms des clients) dont le total est supérieur ou égal au total
de la commande numéro 20.
1.
Déterminez les dépendances référentielles et existentielles.
2.
Décrivez le graphe de relations.
3.
Ecrivez les commandes SQL pour créer les tables et spécifier leur
identifiant ainsi que leurs clés étrangères.
Décrire la
portée de RI pour faciliter l’implémentation de RI validation
·
Contexte : classes (relations) sur lesquelles une RI est définie ou
validée.
·
Risque : primitive sur la classe de contexte dont l’exécution risque
de transgresser
Avec :
·
Colonne : primitives (créer, supprimer, mettre à jour)
·
Ligne : class de contexte.
·
Case : oui si la primitive est un risque ; non si
non. En plus, pour la mise à jour, préciser l’attribut qui est effectué par
cette primitive.
Par exemple :
L'état de
livraison est soit 'Acceptée' soit 'Refusée'
|
Ajouter |
Supprimer |
Mise à jour |
LIVRCDE |
Oui |
Non |
EtatLivr |
1.
Trouver les faux dans le tableau de portée des RI suivantes.
1.1. La date d'une commande doit être antérieure à celle des livraisons de cette
commande.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
Oui |
Non |
Non |
LIVRCDE |
Oui |
Oui |
DateLivr |
1.2. Une livraison doit s'effectuer dans les 15 jours suivant la commande.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
Oui |
Non |
DateCde |
LIVRCDE |
Non |
Non |
Non |
1.3. Pour une commande, il y a au moins un produit commandé.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
Non |
Non |
NumClient |
LIGNECDE |
Oui |
Oui |
Non |
1.4. Le total d'une commande doit être la somme des produits de la quantité et
du prix des produits commandés.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
Oui |
Non |
Non |
LIGNECDE |
Oui |
Non |
QuantiteProdCde |
PRODUIT |
Non |
Oui |
Non |
1.5. Si une livraison est acceptée, aucun renvoi de cette livraison n'est
enregistré.
|
Ajouter |
Supprimer |
Mise à jour |
LIVRCDE |
Non |
Non |
EtatLivr |
RENVOI |
Non |
Non |
NumLiv |
2.
Déterminer le tableau de portée pour les RI données.
2.1. Le renvoi d'une livraison ne peut avoir lieu qu'après la date de livraison.
2.2. Les produits défectueux doivent être retournés dans les 5 jours suivant la
livraison.
2.3. La quantité totale des produits livrés qui sont acceptés ne doivent pas
être supérieure à celle commandée.
2.4. Pour une livraison d'une commande, il faut avoir au moins un produit livré
qui est enregistré.
2.5. Une livraison refusée doit avoir un renvoi de cette livraison enregistré.
Il s'agit de
la gestion du parc automobile d'une organisation.
Voici les
attributs retenus :
Attributs :
numéro-voiture NOV mot
marque-voiture MV texte
nombre de kilomètres KM numérique positif de
parcouru
nombre de places de passagers PSG entier (1,5)
nom-chauffeur CHAUFFEUR texte
numéro-chauffeur NCH entier (0,100)
nombre de kilomètres NKM numérique positif de km
numéro-réparation NOREP entier (0,1000)
type-réparation TYPEREP mot
montant PX numérique positif de FS
nombre de kilomètres KMCPT numérique positif de km au
compteur
date-trajet DATE_TRAJET (entier
(0,99),
entier (0,12),
entier (0,31))
ville-départ VILLEDEP ville
ville-arrivée VILLEARR
ville
ville VILLE mot
numéro-trajet NOTRAJ entier
nombre de personnes transportées NBPERSTR nombre de places de passagers
numéro de garage de réparation NOG entier (0,100)
nom du garage G texte
distance en kilomètres NBKM numérique positif de km (0,500)
Relations :
VOITURE
(NOV, MV, KM, PSG)
prédicat : à
une voiture on associe son numéro de voiture NOV qui la distingue des autres
voitures, sa marque MV, le nombre de kilomètres qu'elle a parcourus KM, le
nombre de places disponibles de passagers PSG.
CH (NCH,
CHAUFFEUR)
prédicat : à
un numéro de chauffeur NCH on associe un seul nom du chauffeur CHAUFFEUR.
V-CH (NOV, NCH,
NKM)
prédicat : le
chauffeur de tel numéro NCH a conduit la voiture de tel numéro NOV pendant tant
de kilomètres NKM depuis que la voiture est en service.
REPARATION
(NOREP, NOV, NOG, TYPREP, PX, KMCPT)
prédicat : la
voiture de tel numéro NOV est menée au garage de tel numéro NOG pour une
réparation de numéro NOREP et de type TYPEREP; elle a alors tant de kilomètres
au compteur KMCPT. Cette réparation a coûté tant PX.
TRAJET (NOTRAJ,
VILLEDEP, VILLEARR, DATE_TRAJET, NBKM)
prédicat : un
trajet de tel numéro NOTRAJ a été effectué à telle date DATE-TRAJET; les villes
de départ et d'arrivée sont respectivement VILLEDEP, VILLEARR; le trajet est de
tant de kilomètres NBKM.
TR-NOV (NOTRAJ,
NOV, NCH, NBPERSTR)
prédicat : la
voiture de numéro NOV, conduite par le chauffeur de numéro NCH, a transporté
tant de personnes (NBPERSTR) pour le trajet de numéro NOTRAJ.
Un
chauffeur peut conduire plusieurs fois la même voiture pour des trajets
différents, et il y a un seul chauffeur qui conduit une voiture au cours d’un
trajet.
1. Déterminer les clés / identifiants des
classes/relations. Indiquer les identifiants obligatoires.
2. Voici
une liste d'affirmations concernant le même champ d'application. Vous
indiquez si elles sont en accord ou en contradiction avec la modélisation
proposée en justifiant votre réponse:
a) c'est toujours le même chauffeur qui conduit
la même voiture;
b) lors d'un trajet, c'est toujours la même
voiture que conduit un chauffeur;
c) l'organisation confie toutes ses voitures à
réparer à un seul garage;
d) il existe des trajets dont la distance
dépasse
e) un cadre de l'entreprise qui n'est pas un
chauffeur peut quand même conduire une voiture pour un trajet;
f) un trajet est assuré par une seule voiture;
g) il existe des voitures de plus de 5 places
pour les passagers.
3. Voici
une liste de questions concernant la modélisation.
a)
Un chauffeur peut-il effectuer plusieurs fois le même trajet ?
b)
Deux chauffeurs différents peuvent-ils effectuer le même trajet ?
c)
Un chauffeur peut-il effectuer plusieurs trajets avec la même voiture ?
d)
Est-ce qu'un trajet peut être effectué à deux dates différentes ?
e)
Un trajet peut-il être effectué par plusieurs voitures ?
1.
Créez les tables et spécifiez leurs contraintes d’identifiant pour les
relations VOITURE , CH, V-CH , REPARATION, TRAJET et TR-NOV.
2.
Insérez des tuples dans les relations ci-dessus en spécifiant les valeurs à
insérer comme suit :
VOITURE
NOV |
MV |
KM |
PSG |
11 |
Honda |
5600 |
5 |
12 |
Ford |
4000 |
4 |
13 |
Honda |
290 |
5 |
14 |
BMW |
100 |
6 |
CH
NCH |
CHAUFFEUR |
1 |
BOUBOU |
2 |
LOULOU |
3 |
NOUNOU |
4 |
LEE |
V_CH
NOV |
NCH |
NKM |
11 |
1 |
2000 |
11 |
2 |
3600 |
12 |
1 |
2200 |
12 |
2 |
1800 |
13 |
3 |
290 |
14 |
4 |
100 |
REPARATION
NOREP |
NOV |
NOG |
TYPREP |
PX |
KMCPT |
551 |
11 |
901 |
A |
5200 |
4000 |
552 |
11 |
902 |
B |
4000 |
4800 |
553 |
11 |
901 |
B |
3000 |
5200 |
554 |
12 |
902 |
C |
<null> |
3000 |
555 |
12 |
903 |
A |
6000 |
3600 |
TRAJET
NOTRAJ |
VILLEDEP |
VILLEARR |
DATE_TRAJET |
NBKM |
101 |
GENEVE |
|
01.01.2000 |
180 |
102 |
GENEVE |
|
15.02.2000 |
60 |
103 |
GENEVE |
|
10.04.2000 |
120 |
108 |
|
|
20.08.2000 |
60 |
109 |
|
|
20.08.2000 |
120 |
110 |
|
|
02.01.2001 |
120 |
201 |
GENEVE |
|
01.01.2000 |
180 |
202 |
GENEVE |
|
16.02.2000 |
60 |
203 |
GENEVE |
|
19.04.2000 |
120 |
208 |
|
|
29.08.2000 |
60 |
209 |
|
GENEVE |
29.01.2001 |
120 |
TR_NOV
NOTRAJ |
NOV |
NCH |
NBPERSTR |
101 |
11 |
1 |
5 |
101 |
12 |
2 |
4 |
102 |
11 |
1 |
4 |
103 |
12 |
2 |
3 |
108 |
13 |
3 |
4 |
109 |
14 |
4 |
6 |
110 |
13 |
3 |
4 |
201 |
13 |
3 |
5 |
202 |
11 |
1 |
5 |
203 |
12 |
2 |
4 |
208 |
13 |
3 |
2 |
209 |
11 |
1 |
5 |
209 |
13 |
3 |
4 |
209 |
12 |
2 |
4 |
3.
Affichez tous les renseignements concernant le trajet no 109.
4.
Recherchez des chauffeurs dont le nom commence par ‘L’ et se termine par
‘E’.
5.
Triez les trajets selon l’ordre alphabétique de leur ville de départ et
l’ordre croissant de leur nombre de kilomètres.
6.
Affichez tous les renseignements concernant des trajets partant de Lausanne
et dont la distance est inférieure à 100 k. Triez les résultats par ordre
alphabétique des villes d’arrivée.
7.
Donnez les numéros des réparations pour lesquelles on a négligé de rentrer
le montant.
8.
Donnez les renseignements concernant les réparations pour la voiture numéro
11 et dont le montant est supérieur ou égal à 4500.
9.
Donnez les numéros des trajets par ordre croissant, les villes de départ,
les villes d’arrivée et les dates
concernant les trajets pour lesquels la distance est comprise entre 150
et 200.
10. Donnez les renseignements
concernant les trajets effectués avant le 31.12.2000 et dont le nombre de
kilomètres est supérieur à 150 ou inférieur à 100.
11. Donnez les renseignements
concernant les trajets qui soit partant de Lausanne et sont de moins de
12. Affichez le nombre moyen, le
nombre minimum, le nombre maximum de kilomètres des trajets qui sont arrivés à Bern?
13. Affichez tous les numéros
des voitures qui ont été réparées au moins deux fois.
14. Affichez par ordre croissant
tous les numéros des voitures qui ont été réparées dont le montant moyen est
supérieur à 2000.
15. Affichez par ordre croissant
tous les numéros des voitures qui n’ont pas été réparées.
16. Quel est le nombre des
voitures réparées par chaque garage ?
17. Pour chaque ville de départ,
donner le moyen, le maximum, et le minimum de nombres de kilomètres effectués
par des trajets.
18. Affichez les voitures qui
ont été réparées au moins trois fois et dont la moyenne des montants des
réparations est supérieure à 3000.
19. Affichez les chauffeurs qui
ont participé au moins à 4 trajets.
20. Quel est le total moyen des
nombres de kilomètres de tous les trajets pendant l’année 2000 ?
21. Donnez la liste de tous les
trajets dont la distance est supérieure à la distance du trajet numéro 208.
1.
Affichez les numéros et les marques de toutes les voitures qui ont été
réparées et dont le montant de la réparation est entre 3000 et 5000; affichez
aussi leur nombre de kilomètres parcourus.
2.
Affichez tous les numéros et les marques des voitures qui ont été conduites
par les chauffeurs LOULOU et NOUNOU; affichez les par ordre décroissant des
numéros.
3.
Affichez tous les numéros et les marques des voitures qui ont été réparées
et dont la moyenne des montants des réparations est entre 3000 et 4000.
4.
Affichez les numéros et les nombres de kilomètres parcourus de toutes les
voitures qui ont été réparées au moins deux fois.
5.
Affichez tous les numéros et les noms des
chauffeurs qui ont participé au moins à 3 trajets pendant les années
1999 et 2000.
6.
Affichez toutes les informations de la voiture qui a effectué le plus de
trajets.
7.
Donnez les numéros, les villes de départ et les villes d’arrivée des
trajets qu’ont effectué les voitures de marque HONDA.
8.
Donnez les numéros, les villes de départ et les villes d’arrivée des
trajets qui, soit ont été assurés par le chauffeur LOULOU, soit sont arrivés à
Lausanne.
9.
Donnez la liste de toutes les voitures (avec leur numéro et leur marque)
dont le nombre de kilomètres est supérieur au nombre de kilomètres de la
voiture numéro 13.
10. Donnez tous les numéros et
les noms des chauffeurs qui ont conduit
les trajets dont la voiture a été réparée par la réparation de numéro 554.
11. Affichez tous les numéros et
les noms des chauffeurs qui ont conduit la voiture 11 au moins deux fois
pendant l’année 2000.
12. Donnez la liste des numéros
des voitures, qui ont fait des trajets à partir de Lausanne de plus de
13. Donnez la liste des numéros
des voitures qui n’ont pas encore fait des trajets pendant l’année 2001.
14. Donnez la liste des numéros
des chauffeurs, avec leur total des distances (en kilomètres) des
trajets effectués.
15. Donnez la liste des numéros
des voitures, avec leur moyenne des montants des réparations.
1.
Trouver le ou les identifiants des relations : PRODUIT, LIGNECDE, LIVRCDEPRODUIT, RENVOI.
PRODUIT (NumProd //
LibelléProd, PrixUnitaireProd)
NumProd va permettre
de distinguer tous les objets de PRODUIT entr’eux puisqu’il identifie les
produits. Ainsi à un objet de PRODUIT va correspondre un et un seul produit.
CLIENT
(NumClient // Nom, Prénom, AdresseClient)
COMMANDE
(NumCde // NumClient, DateCde, Total, AdresseLivraison)
LIGNECDE
(NumCde, NumProd // QuantiteProdCde)
D’après le texte une commande porte sur plusieurs produits,
et bien sûr on suppose qu’à un produit peuvent correspondre plusieurs
commandes ! Donc les deux attributs NumCde et NumProd forment un
identifiant de LIGNECDE.
LIVRCDE
(NumLiv, NumCde // DateLivr, EtatLivr)
LIVRCDEPRODUIT (NumLiv, NumCde, NumProd //
QteLivrée)
D’après le texte, à une livraison de commande
peuvent correspondre plusieurs produits : donc NumProd doit faire partie
de l’identifiant.
Nulle part on prescrit qu’un produit d’une commande
doit être livré en une seule fois et ainsi être associé à un seul NumLiv, donc
NumLiv doit faire partie de l’identifiant.
Donc l’identifiant se compose de NumLiv, NumCde et
de NumProd.
RENVOI
(NumLiv, NumCde // DateRenvoi)
A
une livraison de commande (NumLiv, NumCde) correspond une seule date de renvoi.
Donc
l’identifiant se forme de NumLiv, NumCde.
2.
Répondre aux questions suivantes en justifiant votre réponse :
a)
Peut-on livrer une commande en plusieurs fois ?
OUI, car l’identifiant de LIVRCDE n’est pas seulement
NumCde.
b)
Une livraison concerne-t-elle une seule commande ?
Quelle est la signification de NumLiv ?
(cas livr1) Si NumLiv permet de distinguer toutes
les livraisons les unes des autres, alors une livraison peut être associée à
plusieurs commandes et la réponse est non.
(cas livr2) Si non, alors NumLiv permet de
distinguer toutes les livraisons d’une même commande les unes des
autres. Mais, dans ce cas, on ne peut pas savoir si une livraison pour une
commande peut oui ou non se combiner avec une livraison d’une autre commande.
La modélisation actuelle ne permet pas de répondre.
En fait le concept même de livraison n’est pas représenté
clairement dans cette modélisation. Ainsi on ne sait pas exactement à quoi
correspond dans le monde vivant un objet de LIVRCDE.
c)
Une livraison concerne-t-elle un seul client ?
Tout dépend si un objet de LIVRCDE représente une
livraison ou seulement une partie d’une livraison.
Par contre, à un objet de LIVRCDE correspond un seul
objet de CDE et donc un seul objet de CLIENT, auquel correspond un seul client.
d)
Une livraison peut-elle concerner un seul produit ?
OUI, rien ne l’empêche, même si la modélisation prévoit
les cas où une livraison puisse concerner plusieurs produits.
e)
Peut-on livrer les quantités d’un
même produit d’une même commande en plusieurs fois ?
OUI, la modélisation le permet car l’identifiant de LIVRCDEPRODUIT contient NumProd.
f)
Peut-on livrer plusieurs commandes en une seule livraison (un seul numéro
de livraison)?
Tout dépend de la signification de NumLiv : s’il
désigne une livraison (cas livr1), la réponse est OUI.
S’il désigne une numéro pour distinguer les livraisons
d’une même commande entr’elles (cas livr2), alors on ne peut rien dire.
g)
Les livraisons d’une commande doivent–elles amener les produits à la même
adresse ?
OUI car c’est l’adresse de livraison stockée au niveau de
COMMANDE.
h)
L’adresse de livraison d’une commande doit-elle être identique à l’adresse
du client?
NON, il n’y a rien qui l’oblige.
i)
Dans une livraison il y a des articles d’un produit qui sont
défectueux. Peut-on simplement les
renvoyer et laisser les articles conformes du même produit de cette
livraison chez le client?
NON, car si l’on renvoie des articles d’un produit d’une
livraison, on renvoie tous les articles du produit de la même livraison !
A moins que le SI ne s’intéresse pas à connaître les articles renvoyés !
j)
Dans une livraison il y a des articles d’un produit qui sont défectueux.
Par contre les articles des autres produits livrés en même temps sont tous
conformes à la commande. Si l’on retourne les articles du produit dont certains
sont défectueux, peut-on laisser les articles des autres produits chez le
client ?
NON, car si l’on renvoie des articles d’un produit d’une
livraison, on renvoie tous les articles de tous les produit et de la même
livraison ! A moins que le SI ne s’intéresse pas à connaître les articles
renvoyés !
k)
Une fois la livraison effectuée peut-on mettre-à-jour la quantité livrée de
produits chez un client ?
OUI, rien ne l’interdit.
1.
Afficher tous les renseignements concernant les clients.
SELECT * FROM client ;
2.
Afficher tous les noms des clients.
SELECT nom FROM client ;
3.
Afficher tous les noms et prénoms des clients.
SELECT nom, prenom FROM client ;
4.
Afficher tous les numéros des clients qui ont passé des commandes.
(Chaque numéro du client sera affiché une
seule fois)
SELECT DISTINCT numclient FROM
commande ;
5.
Afficher tous les renseignements concernant les clients par ordre
alphabétique.
SELECT * FROM client ORDER BY nom ;
6.
Triez les commandes selon l’ordre croissant de leur totaux.
SELECT * FROM commande ORDER BY
total ;
7.
Affichez tous les renseignements concernant le client no 2.
SELECT * FROM client WHERE numclient =
2 ;
8.
Affichez tous les renseignements concernant le client dont le nom commence
par ‘L’.
Solution
1:
SELECT
* FROM client WHERE SUBSTR(nom,1,1) = 'L' ;
Solution
2:
SELECT
* FROM client WHERE nom LIKE 'L%' ;
9.
Sélectionnez toutes les commandes dont le total de la commande est supérieur
à 1000 par ordre croissant.
SELECT * FROM commande WHERE total > 1000
ORDER BY total ;
10.
Donnez les numéros des commandes, les numéros des clients, les dates des
commandes et les totaux des commandes pour lesquels le total est entre 800 et
1000 par ordre chronologique.
Solution
1:
SELECT numcde, numclient, datecde, total
FROM commande
WHERE (total >= 800) AND (total <=
1000) ORDER BY datecde ;
Solution
2:
SELECT numcde, numclient, datecde, total
FROM commande
WHERE total BETWEEN 800 AND 1000 ORDER BY
datecde ;
11. Donnez les renseignements concernant
les commandes pour lesquelles le total est supérieur à 1000 ou inférieur à 100
Solution
1:
SELECT * FROM commande WHERE total >
1000
SELECT * FROM commande WHERE total <
100 ;
Solution
2:
SELECT * FROM commande WHERE (total >
1000) OR (total < 100) ;
Solution
3:
SELECT * FROM commande WHERE total NOT
BETWEEN 100 AND 1000 ;
12. Donnez
les numéros des commandes, les numéros des clients, les dates des commandes et
les totaux des commandes pour lesquels le total n’est pas supérieur à 100.
Solution
1:
SELECT numcde, numclient, datecde, total
FROM commande
WHERE NOT total > 100;
Solution
2:
SELECT numcde, numclient, datecde, total
FROM commande WHERE total <=100;
13. Donnez les noms, prénoms
des clients qui n’ont pas d’adresse.
SELECT
nom, prenom FROM client WHERE adresseclient IS NULL ;
14.
Donnez les renseignements concernant les livraisons datées avant le
01.01.2000 et son état est ‘Refusée’.
Solution 1:
SELECT * FROM livrcde WHERE datelivr < '01-01-00'
INTERSECT
SELECT * FROM livrcde WHERE etatlivr = 'Refusée';
Solution 2:
SELECT * FROM livrcde
WHERE (datelivr) < '01-01-00' AND (etatlivr =
'Refusée');
15.
Donnez les numéros des livraisons et leurs dates, concernant la commande
10 et dont l’état n’est pas ‘Acceptée’.
Solution 1:
SELECT numliv, datelivr FROM livrcde WHERE numcde = 10
MINUS
SELECT numliv, datelivr FROM livrcde WHERE etatlivr = 'Acceptée';
Solution 2:
SELECT numliv, datelivr FROM livrcde
WHERE (numcde = 10) AND (etatlivr <> 'Acceptée');
16. Donnez les
renseignements concernant les commandes datées après le 31.12.1999 et son total
est entre 100 et 5000.
Solution 1:
SELECT * FROM commande WHERE datecde > '31-12-99'
INTERSECT
SELECT * FROM commande WHERE total BETWEEN 100 AND
5000;
Solution 2:
SELECT * FROM commande
WHERE (datecde > '31-12-99') AND (total BETWEEN 100
AND 5000);
17. Quel est le total moyen des
commandes passées après le 01.01.2001 et avant 30.06.2001 ?
SELECT AVG(total) FROM commande
WHERE datecde BETWEEN '01-01-01' AND '30-06-01' ;
18. Affichez la quantité, les
totaux maximum et minimum des commandes de l’année 2000.
SELECT COUNT(*), MAX(total), MIN(total) FROM commande
WHERE datecde BETWEEN '01-01-00' AND '31-12-00' ;
19. Quel est le total moyen des
commandes effectuées par un client ?
SELECT AVG(total) FROM commande GROUP BY
numclient ;
20. Affichez les clients qui
ont passé des commandes dont la moyenne des totaux est supérieure à 1000.
Solution 1:
SELECT DISTINCT numclient FROM commande
GROUP BY numclient HAVING AVG(total) > 1000 ;
Solution 2:
SELECT DISTINCT numclient, nom, prenom, adresse FROM
client
WHERE numclient IN
( SELECT
numclient FROM commande
GROUP BY numclient HAVING AVG(total) > 1000
) ;
1.
Créez les tables et spécifiez leurs contraintes d’identifiant pour les
relations
PRODUIT
SQL>
1
CREATE TABLE produit (
2
NumProd NUMBER(3) CONSTRAINT pk_produit PRIMARY KEY,
3 LibelleProd
CHAR(20),
4
PrixUnitaireProd NUMBER(10,2)
5* CONSTRAINT
ck_PrixUnitaireProd CHECK (PrixUnitaireProd >= 0))
Table
créée.
CLIENT
SQL>
1
CREATE TABLE client (
2
NumClient NUMBER(3) CONSTRAINT pk_client PRIMARY KEY,
3 Nom
CHAR(24),
4
Prenom CHAR(24),
5*
AdresseClient CHAR(80))
Table créée.
COMMANDE
SQL>
1
CREATE TABLE commande (
2
NumCde NUMBER(3) CONSTRAINT pk_commande PRIMARY KEY,
3
NumClient NUMBER(3) NOT NULL,
4 DateCde
DATE,
5
Total NUMBER(11,2) CONSTRAINT ck_Total CHECK (Total >= 0),
6* AdresseLivraison CHAR(80))
Table
créée.
LIGNECDE
SQL>
1 CREATE TABLE lignecde (
2
NumCde NUMBER(3) NOT NULL,
3
NumProd NUMBER(3) NOT NULL,
4 QuantiteProdCde
NUMBER(3),
5*
CONSTRAINT pk_lignecde PRIMARY KEY (NumCde, NumProd) )
Table
créée.
LIVRCDE
SQL>
1
CREATE TABLE livrcde (
2
NumLiv NUMBER(3) NOT NULL,
3
NumCde NUMBER(3) NOT NULL,
4
DateLivr DATE,
5 EtatLivr CHAR(10)
6
CONSTRAINT ck_etatlivr CHECK (etatlivr IN ('ACCEPTE', 'REFUSEE')),
7* CONSTRAINT pk_livrcde PRIMARY KEY (NumLiv,
NumCde) )
Table
créée.
LIVRCDEPRODUIT
SQL>
1
CREATE TABLE livrcdeprod (
2
NumLiv NUMBER(3) NOT NULL,
3
NumCde NUMBER(3) NOT NULL,
4
NumProd NUMBER(3) NOT NULL,
5
QteLivree NUMBER(3),
6*
CONSTRAINT pk_livrcdeprod PRIMARY KEY (NumLiv, NumCde, NumProd) )
Table
créée.
RENVOI
SQL>
1
CREATE TABLE renvoi (
2 NumLiv
NUMBER(3) NOT NULL,
3
NumCde NUMBER(3) NOT NULL,
4 DateRenvoi DATE,
5*
CONSTRAINT pk_renvoi PRIMARY KEY (NumLiv, NumCde) )
Table
créée.
2.
Insérez des tuples dans les
relations ci-dessus en spécifiant les valeurs à insérer comme suit :
PRODUIT
INSERT
INTO produit VALUES (111, 'NOTEBOOK', 3000);
INSERT
INTO produit VALUES (112, 'IMPRIMANTE', 500);
INSERT
INTO produit VALUES (113, 'SCANNER', 200)
CLIENT
INSERT
INTO client VALUES (1, 'MENU','NILOLAS', 'GENERAL DUFOUR, 24');
INSERT
INTO client VALUES (2, 'LEE','ROBERTO', 'MIREMONT, 46');
INSERT
INTO client VALUES (3, 'BLOND','ALEXANDRE', 'RUE DE LAUSANNE, 01')
COMMANDE
INSERT
INTO commande VALUES (10, 1, '15-12-99',
32500, 'GÉNÉRAL DUFOUR, 24') ;
INSERT
INTO commande VALUES (20, 2, '20-01-00',
24500, 'RUE DE LYON, 03') ;
INSERT
INTO commande VALUES (30, 1,
'18-06-00', 2500, 'MIREMONT, 29') ;
INSERT
INTO commande VALUES (40, 3,
'20-09-00', 6000, 'RUE DE LAUSANNE, 01')
;
INSERT
INTO commande VALUES (50, 1,
'30-12-00', 1600, 'GÉNÉRAL DUFOUR, 24' )
;
INSERT
INTO commande VALUES (60, 2,
'07-01-01', 3100, 'RUE DE GENÈVE, 120')
LIGNECDE
INSERT INTO lignecde VALUES (10,111,10) ;
INSERT INTO lignecde VALUES (10,112,5) ;
INSERT INTO lignecde VALUES (20,111,8) ;
INSERT INTO lignecde VALUES (30,112,5) ;
INSERT INTO lignecde VALUES (40,111,2) ;
INSERT INTO lignecde VALUES (50,113,8) ;
INSERT INTO lignecde VALUES (60,112,5) ;
INSERT INTO lignecde VALUES (60,113,3)
LIVRCDE
INSERT
INTO livrcde VALUES (901,10,'25.01.00','ACCEPTE');
INSERT
INTO livrcde VALUES (901,20,'25.01.00','ACCEPTE');
INSERT
INTO livrcde VALUES (902,30,'30.06.00','ACCEPTE');
INSERT
INTO livrcde VALUES (903,40,'30.09.00','REFUSEE');
INSERT
INTO livrcde VALUES (904,50,'02.01.01','ACCEPTE');
INSERT
INTO livrcde VALUES (904,60,'10.01.01','ACCEPTE')
LIVRCDEPRODUIT
INSERT
INTO livrcdeprod VALUES (901,10,111,10);
INSERT
INTO livrcdeprod VALUES (901,10,112,5);
INSERT
INTO livrcdeprod VALUES (901,20,111,8);
INSERT
INTO livrcdeprod VALUES (902,30,112,5);
INSERT
INTO livrcdeprod VALUES (903,40,111,0);
INSERT
INTO livrcdeprod VALUES (904,50,113,8);
INSERT
INTO livrcdeprod VALUES (904,60,112,5);
INSERT
INTO livrcdeprod VALUES (904,60,113,3)
RENVOI
INSERT INTO renvoi VALUES (903,40,'30-09-00')
3.
Affichez tous les numéros, libellés, prix unitaires des produits qui correspondent à
la commande 10.
SQL>
1
SELECT PD.NumProd, LibelleProd, PrixUnitaireProd FROM produit PD ,
lignecde LCD
2*
WHERE (PD.NumProd = LCD.NumProd) AND (LCD.NumCde = 10)
NUMPROD LIBELLEPROD PRIXUNITAIREPROD
----------
-------------------- ----------------
111 NOTEBOOK 3000
112 IMPRIMANTE 500
4.
Affichez tous les noms,
prénoms, adresses des clients qui effectuent des commandes datées après le
31.12.99.
SQL>
1
SELECT DISTINCT Nom, Prenom, AdresseClient FROM Client CLT, commande CDE
2* WHERE (CLT.NumClient =
CDE.NumClient) AND (DateCde > '31-12-99')
NOM PRENOM ADRESSECLIENT
------------------------------------------------------------------------------------------------------------------------
BLOND ALEXANDRE RUE DE
LAUSANNE, 01
LEE ROBERTO MIREMONT,
46
MENU NILOLAS GENERAL
DUFOUR, 24
5.
Affichez tous les noms,
prénoms des clients qui effectuent les commandes datées pendant l’année 2000 et
son total est entre 1000 et 5000.
SQL>
1
SELECT DISTINCT Nom, Prenom FROM Client CLT, commande CDE
2
WHERE (CLT.NumClient = CDE.NumClient) AND
3
(DateCde BETWEEN '01-01-00' AND '31-12-00') AND
4*
(Total BETWEEN 1000 AND 5000)
NOM PRENOM
------------------------
------------------------
MENU NILOLAS
6.
Affichez tous les numéros des
commandes, dates des livraisons, numéros des clients, noms des clients, prénoms
des clients concernant les livraisons pour la commande 10.
SQL>
1
SELECT DISTINCT CDE.NumCde, DateLivr, CLT.NumClient, Nom, Prenom
2
FROM Client CLT, commande CDE, livrcde LIV
3 WHERE (CLT.NumClient = CDE.NumClient) AND
4
(CDE.NumCde = LIV.NumCde) AND
5*
(CDE.NumCde = 10)
NUMCDE DATELIVR NUMCLIENT NOM PRENOM
----------
-------- ---------- ------------------------ ------------------------
10 25/01/00 1 MENU NILOLAS
7.
Affichez tous les numéros
des clients, noms des clients, prénoms des clients, numéros des commandes,
dates des livraisons concernant les livraisons pour la commande 30 et dont
l’état de la livraison n’est pas ‘Accepté’.
SQL>
1
SELECT DISTINCT CLT.NumClient, Nom, Prenom, CDE.NumCde, DateLivr
2
FROM Client CLT, commande CDE, livrcde LIV
3
WHERE (CLT.NumClient = CDE.NumClient) AND
4 (CDE.NumCde = LIV.NumCde) AND
5
(CDE.NumCde = 30) AND
6* (EtatLivr <> 'ACCEPTE')
aucune
ligne sélectionnée
8.
Affichez tous les noms,
prénoms des clients qui effectuent les commandes pour lesquels le total moyen
est supérieur à 10000.
SQL>
1
SELECT DISTINCT Nom, Prenom, AdresseClient
2
FROM Client CLT
3
WHERE NumClient IN
4
(SELECT NumClient FROM commande
5
GROUP BY NumClient
6* HAVING AVG(Total) > 10000)
NOM PRENOM ADRESSECLIENT
--------------------------------------------------------------------------------
LEE ROBERTO MIREMONT, 46
MENU NILOLAS GENERAL DUFOUR, 24
9.
Affichez tous les noms,
prénoms, adresses des clients qui ont effectué le produit 112 pendant l’année
2000.
SQL>
1
SELECT DISTINCT Nom, Prenom, AdresseClient
2
FROM Client CLT, commande CDE, lignecde LCD
3 WHERE (CLT.NumClient = CDE.NumClient) AND
4
(CDE.NumCde = LCD.NumCde)
AND
5
(NumProd = 112) AND
6*
(DateCde BETWEEN '01-01-00' AND '31-12-00')
NOM PRENOM ADRESSECLIENT
---------------------------------------------------------------------------------------------------------------------
MENU NILOLAS GENERAL DUFOUR, 24
10.
Donnez la liste de toutes
les commandes (incluant les numéros des commandes, numéros des clients, noms
des clients, prénoms des clients) dont le total est supérieur ou égal au total
de la commande numéro 20.
SQL>
1
SELECT DISTINCT CDE1.NumCde, CLT.NumClient, Nom, Prenom
2
FROM Client CLT , commande CDE1
3
WHERE (CLT.NumClient = CDE1.NumClient) AND
4
CDE1.Total >=
5 (SELECT CDE2.Total FROM commande CDE2
6* WHERE
CDE2.NumCde = 20)
NUMCDE
NUMCLIENT NOM
PRENOM
----------
---------- ------------------------ ------------------------
10 1 MENU NILOLAS
20 2 LEE ROBERTO
Déterminez les dépendances référentielles (DR) et
existentielles (DE).
COMMANDE [NumClient] Í CLIENT [NumClient] (DR)
LIGNECDE [NumCde] Í COMMANDE [NumCde] (DE)
LIGNECDE [NumProd] Í PRODUIT [NumProd] (DE)
LIVRCDE [NumCde] Í COMMANDE [NumCde] (DE)
LIVRCDEPRODUIT [NumLiv, NumCde] Í LIVRCDE [NumLiv, NumCde] (DE)
LIVRCDEPRODUIT [NumProd, NumCde] Í LIGNECDE [NumProd, NumCde] (DE)
RENVOI [NumLiv, NumCde] Í LIVRCDE [NumLiv, NumCde] (DE)
Etablissez le graphe de relations
Créez les tables et spécifiez leur identifiant
ainsi que leurs clés étrangères.
CREATE TABLE
produit (
numprod NUMBER(10) CONSTRAINT
pk_produit PRIMARY KEY,
libelleprod CHAR(50),
prixunitaireprod NUMBER(6,2)
) ;
CREATE TABLE
client (
numclient NUMBER(10) CONSTRAINT
pk_client PRIMARY KEY,
nom CHAR(20),
prenom CHAR(20),
adressclient CHAR(60)
);
CREATE TABLE
commande (
numcde NUMBER(10) CONSTRAINT
pk_commande PRIMARY KEY,
numclient NUMBER(10) CONSTRAINT fk_cl REFERENCES
client,
datecde DATE,
total NUMBER(10,2),
adresslivraison CHAR(60)
);
CREATE TABLE
lignecde (
numcde NUMBER(10) CONSTRAINT
fk_lg_cde
REFERENCES
commande ON DELETE CASCADE,
numprod NUMBER(10) CONSTRAINT
fk_lg_prod
REFERENCES
produit ON DELETE CASCADE,
quantiteprodcde NUMBER(4),
CONSTRAINT
pk_lignecde PRIMARY KEY (numcde, numprod)
);
CREATE TABLE
livrcde (
numliv NUMBER(10),
numcde NUMBER(10) CONSTRAINT
fk_lv_cde
REFERENCES commande ON DELETE CASCADE,
datelivr DATE,
etatlivr CHAR(8),
CONSTRAINT pk_livrcde PRIMARY KEY (numliv, numcde)
);
CREATE TABLE
livrcdeproduit (
numliv NUMBER(10),
numcde NUMBER(10),
numprod NUMBER(10),
qtelivree NUMBER(4),
CONSTRAINT
pk_livrcdepro PRIMARY KEY (numliv, numcde, numprod),
CONSTRAINT
fk_livrcde FOREIGN KEY (numliv, numcde)
REFERENCES
livrcde ON DELETE CASCADE,
CONSTRAINT
fk_lignecde FOREIGN KEY (numcde, numprod)
REFERENCES
lignecde ON DELETE CASCADE
);
CREATE TABLE
renvoi(
numliv NUMBER(10),
numcde NUMBER(10),
daterenvoi DATE,
CONSTRAINT
pk_renvoi PRIMARY KEY (numliv, numcde),
CONSTRAINT
fk_renvoi FOREIGN KEY (numliv, numcde)
REFERENCES livrcde ON DELETE CASCADE
);
Trouver les faux dans le tableau de portée des RI
suivantes.
1.1 La date d'une commande
doit être antérieure à celle des livraisons de cette commande.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
|
Non |
|
LIVRCDE |
Oui |
|
DateLivr |
1.2 Toute livraison doit être effectuée
dans les 15 jours suivant la commande.
|
Ajouter |
Supprimer |
Mise à
jour |
COMMANDE |
|
Non |
DateCde |
LIVRCDE |
|
Non |
|
1.3 Pour une commande, il y a au moins un produit
commandé.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
|
Non |
|
LIGNECDE |
|
Oui |
Non |
1.4 Le total d'une commande doit être la somme des
montants des produits commandés, ces montants sont égaux au produit de la
quantité et du prix des produits commandés.
|
Ajouter |
Supprimer |
Mise à jour |
COMMANDE |
Oui |
Non |
|
LIGNECDE |
Oui |
|
QuantiteProdCde |
PRODUIT |
Non |
Oui |
|
1.5 Si une livraison est acceptée, aucun renvoi de
cette livraison n'est enregistré.
|
Ajouter |
Supprimer |
Mise à jour |
LIVRCDE |
Non |
Non |
EtatLivr |
RENVOI |
|
Non |
|
Déterminer le tableau de portée pour les RI
données.
2.1 Le renvoi d'une livraison ne peut avoir lieu
qu'après la date de livraison.
|
Ajouter |
Supprimer |
Mise à jour |
RENVOI |
Oui |
Non |
DateRenvoi |
LIVRCDE |
Non |
Non |
DateLivr |
2.2 Les produits défectueux doivent être retournés
dans les 5 jours suivant la livraison.
|
Ajouter |
Supprimer |
Mise à jour |
RENVOI |
Oui |
Non |
DateRenvoi |
LIVRCDE |
Non |
Non |
DateLivr |
2.3 La quantité totale des produits livrés qui
sont acceptés ne doivent pas être supérieure à celle commandée.
|
Ajouter |
Supprimer |
Mise à jour |
LIGNECDE |
Non |
Non |
QuantiteProdCde |
LIVRCDE |
Non |
Non |
EtatLivr |
LIVRCDEPRODUIT |
Oui |
Non |
QteLivrée |
2.4 Pour une livraison d'une commande, il faut
avoir au moins un produit livré qui soit enregistré.
|
Ajouter |
Supprimer |
Mise à
jour |
LIVRCDE |
Oui |
Non |
Non |
LIGNECDE |
Non |
Oui |
Non |
LIVRCDEPRODUIT |
Non |
Oui |
Non |
2.5 Une livraison
refusée doit avoir un renvoi de cette livraison enregistré.
|
Ajouter |
Supprimer |
Mise à jour |
LIVRCDE |
Oui |
Non |
EtatLivr |
RENVOI |
Non |
Oui |
Non |
1. Déterminer
les clés / identifiants des classes/relations. Indiquer les identifiants
obligatoires.
VOITURE (NOV
// MV,KM,PSG)
CH (NCH //
CHAUFFEUR)
V-CH
(NOV,NCH // NKM)
REPARATION
(NOREP,NOV // NOG,TYPREP,PX,KMCPT)
TRAJET (NOTRAJ //
VILLEDEP,VILLEARR,DATE,NBKM)
TR-NOV
(NOTRAJ,NOV / NOTRAJ,NCH // NBPERSTR)
Pour les tables
où il y a un seul identifiant, l’identifiant est obligatoire.
Pour la classe
TR-NOV, nous considérons NOTRAJ, NCH comme obligatoire ainsi que NOTRAJ, NOV.
Si NOTRAJ, NOV
n’était pas obligatoire
-
alors on pourrait construire des objets de TR-NOV sans connaître la voiture
qui va être utilisée pour le trajet
-
et on pourrait modifier la voiture d’un trajet.
Remarque : changer la voiture avant le trajet
lui-même peut être très utile au cours du processus d’affectation des voitures
à des trajets.
2. Voici une liste d'affirmations concernant le même champ
d'application. Vous indiquez si elles sont en accord ou en contradiction avec
la modélisation proposée en justifiant votre réponse:
-
c'est toujours le même chauffeur qui conduit la même voiture;
NON ; si c’était
vrai, ce serait NOV qui serait clé de V-CH.
-
lors d'un trajet, c'est toujours la même voiture que conduit un chauffeur;
OUI, car NOTRAJ, NCH
et NOTRAJ, NOV sont des identifiants obligatoires.
-
l'organisation confie toutes ses voitures à réparer à un seul garage;
Rien ne permet de
l’affirmer dans la modélisation. Si c’était le cas, NOG serait un attribut
inutile, le garage devenant un concept implicite de la modélisation, qui n’a
plus besoin d’être représenté comme un attribut.
-
il existe des trajets dont la distance dépasse
D’après le domaine de
NBKM, les distances maximales d’un objet de la classe TRAJET sont de
-
un cadre de l'entreprise qui n'est pas un chauffeur peut quand même
conduire une voiture pour un trajet;
Le SI, tel qu’il est
modélisé , ne permet de prendre en compte le fait qu’un cadre a conduit une
voiture pour un trajet que s’il est enregistré comme chauffeur. Sinon le trajet
effectué par une voiture doit être affecté à un chauffeur et rien ne dit dans
le SI que ce chauffeur a toujours conduit la voiture.
-
un trajet est assuré par une seule voiture;
Non, car un
identifiant de TR-NOV est formé de NOTRAJ, NOV : donc comme NOTRAJ et NOV
sont respectivement des identifiants de TRAJET et de VOITURE, à un trajet peut correspondre
plusieurs voitures.
-
il existe des voitures de plus de 5 places pour les passagers.
Non. Le SI ne peut prendre en compte que
des objets de VOITURE, représentant chacun une voiture du monde vivant, prenant
une valeur inférieure ou égale à 5 pour PSG. Si la modélisation est correcte,
c’est donc qu’il existe pas de voiture disposant de plus de 5 places pour les
passagers.
3. Voici
une liste de questions concernant la modélisation.
1)
Un chauffeur peut-il effectuer plusieurs fois le
même trajet ?
Normalement non si la modélisation indique
qu’un objet de TR-NOV représente le trajet effectué par un chauffeur. Si on
l’acceptait, alors il faudrait que le chauffeur conduisît la même voiture et
l’on rentrerait dans des acrobaties où l’on est sûr d’une chose, la perte de la
crédibilité du SI.
2)
Deux chauffeurs différents peuvent-ils effectuer
le même trajet ?
Oui. Un identifiant de TR-NOV est formé de
NOTRAJ, NCH et ainsi à un trajet identifié par NOTRAJ peut être associé
plusieurs chauffeurs identifiés par NCH.
3)
Un chauffeur peut-il effectuer plusieurs trajets
avec la même voiture ?
OUI, dans les identifiants de TR-NOV, rien
ne l’interdit .
4)
Est-ce qu'un trajet peut être effectué à deux
dates différentes ?
Non, car un objet de TRAJET ne peut qu’une
valeur pour DATE-TRAJET.
5)
Un trajet peut-il être effectué par plusieurs
voitures ?
OUI, à cause de l’identifiant de
TR-NOV : NOTRAJ, NOV.
1.
Créez les tables et
spécifiez leurs contraintes d’identifiant pour les relations VOITURE , CH,
V-CH , REPARATION, TRAJET et TR-NOV.
VOITURE
CREATE TABLE voiture (
nov
CHAR(12) CONSTRAINT pk_voiture PRIMARY KEY,
mv
CHAR(20),
km
NUMBER(6,0) CONSTRAINT ck_km CHECK (km >= 0),
psg NUMBER(2,0) CONSTRAINT ck_psg CHECK (psg
BETWEEN 1 AND 12 ))
CH
CREATE TABLE ch (
nch
NUMBER(3,0) CONSTRAINT pk_ch PRIMARY KEY
CONSTRAINT
ck_nch CHECK (nch BETWEEN 0 AND 100),
chauffeur
CHAR(40))
V-CH
CREATE TABLE v_ch (
nov
CHAR(12),
nch
NUMBER(3,0),
nkm
NUMBER(6,0) CONSTRAINT ck_nkm CHECK (nkm >= 0),
CONSTRAINT
pk_v_ch PRIMARY KEY (nov,nch) )
REPARATION
CREATE TABLE reparation (
norep
NUMBER(4,0) CONSTRAINT ck_norep
CHECK (norep
BETWEEN 0 AND 1000),
nov
CHAR(12),
nog
NUMBER(3,0) CONSTRAINT ck_nog
CHECK (nog
BETWEEN 0 AND 1000),
typerep
CHAR(12),
px
NUMBER(12,2) CONSTRAINT ck_px CHECK (px >= 0),
kmcpt
NUMBER(10,0) CONSTRAINT ck_kmcpt CHECK (kmcpt >= 0),
CONSTRAINT
pk_reparation PRIMARY KEY (norep,nov) )
TRAJET
CREATE TABLE trajet (
notraj
INTEGER CONSTRAINT pk_trajet PRIMARY KEY,
villedep
CHAR(20),
villearr
CHAR(20),
datetrajet
DATE,
nbkm
NUMBER(3,0) CONSTRAINT ck_nbkm
CHECK
(nbkm BETWEEN 0 AND 500))
TR-NOV.
CREATE TABLE tr_nov (
notraj
INTEGER,
nov
CHAR(12),
nch
NUMBER(3,0),
nbperstr
NUMBER(2,0),
CONSTRAINT
pk_tr_nov PRIMARY KEY (notraj,nov) )
2.
Insérez des tuples dans les
relations ci-dessus en spécifiant les valeurs à insérer comme suit :
VOITURE
INSERT INTO voiture VALUES ('11','HONDA', 5600, 5) ;
INSERT INTO voiture VALUES ('12','FORD', 4000, 4);
INSERT INTO voiture VALUES ('13','HONDA', 290, 5) ;
INSERT INTO voiture VALUES ('14','BMW',100, 6)
CH
INSERT INTO ch VALUES (1, 'BOUBOU');
INSERT INTO ch VALUES (2, 'LOULOU');
INSERT INTO ch VALUES (3, 'NOUNOU') ;
INSERT INTO ch VALUES (4, 'LEE')
V_CH
INSERT INTO v_ch VALUES ('11', 1, 2000);
INSERT INTO v_ch VALUES ('11', 2, 3600);
INSERT INTO v_ch VALUES ('12', 1, 2200);
INSERT INTO v_ch VALUES ('12', 2, 1800);
INSERT INTO v_ch VALUES ('13', 3, 290) ;
INSERT INTO v_ch VALUES ('14',4, 100)
REPARATION
INSERT INTO reparation VALUES (551, '11', 901, 'A',
5200, 4000) ;
INSERT INTO reparation VALUES (552, '11', 902, 'B',
4000, 4800);
INSERT INTO reparation VALUES (553, '11', 901, 'B',
3000, 5200);
INSERT INTO reparation (norep, nov, nog, typerep,
kmcpt)
VALUES (554, '12', 902, 'C', 3000) ;
INSERT INTO reparation VALUES (555, '12', 903, 'A',
6000, 3600)
TRAJET
INSERT INTO trajet VALUES (101, 'GENEVE', '
INSERT INTO trajet VALUES (102, 'GENEVE', '
INSERT INTO trajet VALUES (103, 'GENEVE', '
INSERT INTO trajet VALUES (108, '
INSERT INTO trajet VALUES (109, '
INSERT INTO trajet VALUES (110, '
INSERT INTO trajet VALUES (201, 'GENEVE', '
INSERT INTO trajet VALUES (202, 'GENEVE', '
INSERT INTO trajet VALUES (203, 'GENEVE', '
INSERT INTO trajet VALUES (208, '
INSERT INTO trajet VALUES (209, '
TR_NOV
INSERT INTO tr_nov VALUES (101, '11', 1, 5);
INSERT INTO tr_nov VALUES (101, '12', 2, 4);
INSERT INTO tr_nov VALUES (102, '11', 1, 4);
INSERT INTO tr_nov VALUES (103, '12', 2, 3);
INSERT INTO tr_nov VALUES (108, '13', 3, 4);
INSERT INTO tr_nov VALUES (109, '14', 4, 6);
INSERT INTO tr_nov VALUES (110, '13', 3, 4);
INSERT INTO tr_nov VALUES (201, '13', 3, 5);
INSERT INTO tr_nov VALUES (202, '11', 1, 5);
INSERT INTO tr_nov VALUES (203, '12', 2, 4);
INSERT INTO tr_nov VALUES (208, '13', 3, 2);
INSERT INTO tr_nov VALUES (209, '11', 1, 5);
INSERT INTO tr_nov VALUES (209, '13', 3, 4);
INSERT INTO tr_nov VALUES (209, '12', 2, 4)
3.
Affichez
tous les renseignements concernant le trajet no 109.
SQL> SELECT * FROM trajet
2 WHERE notraj = 109
3 /
NOTRAJ
VILLEDEP VILLEARR DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
109
LAUSANNE ZURICH 20-AUG-00 120
4.
Recherchez
des chauffeurs dont le nom commence par ‘L’ et se termine par ‘E’.
SQL>
1* SELECT *
FROM ch WHERE TRIM(chauffeur) LIKE 'L%E'
SQL> /
NCH
CHAUFFEUR
---------- ----------------------------------------
4 LEE
5.
Triez les
trajets selon l’ordre alphabétique de leur ville de départ et l’ordre croissant
de leur nombre de kilomètres.
SQL>
1 SELECT * FROM trajet
2* ORDER BY villedep , nbkm
SQL> /
NOTRAJ VILLEDEP
VILLEARR
DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
209
102
GENEVE
202
GENEVE
103
GENEVE
203 GENEVE
101
GENEVE
201
GENEVE
108
208
109 LAUSANNE ZURICH 20-AUG-00 120
110
LAUSANNE ZURICH 02-JAN-01 120
11 rows selected.
6.
Affichez
tous les renseignements concernant des trajets partant de Lausanne et dont la
distance est inférieure à 100 k. Triez les résultats par ordre alphabétique des
villes d’arrivée.
SQL>
1 SELECT * FROM trajet
2 WHERE (villedep = '
3* ORDER BY villearr
SQL> /
NOTRAJ VILLEDEP
VILLEARR
DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
108
LAUSANNE BERN 20-AUG-00 60
208
LAUSANNE BERN 29-AUG-00 60
7.
Donnez les
numéros des réparations pour lesquelles on a négligé de rentrer le montant.
SQL>
1 SELECT norep FROM reparation WHERE px IS NULL
2 /
NOREP
----------
554
8.
Donnez les
renseignements concernant les réparations pour la voiture numéro 11 et dont le
montant est supérieur ou égal à 4500.
SQL>
1 SELECT * FROM reparation
2* WHERE (nov = '11') AND (px >= 4500)
SQL> /
NOREP NOV NOG TYPEREP PX KMCPT
---------- ------------ ---------- ------------
---------- ----------
551 11
9.
Donnez les
numéros des trajets par ordre croissant, les villes de départ, les villes
d’arrivée et les dates concernant les
trajets pour lesquels la distance est comprise entre 150 et 200.
SQL>
1 SELECT notraj, villedep, villearr, datetrajet
2
FROM trajet
3 WHERE nbkm BETWEEN 150 AND 200
4* ORDER BY notraj
SQL> /
NOTRAJ VILLEDEP
VILLEARR DATETRAJE
---------- -------------------- --------------------
---------
101
GENEVE ZURICH 01-JAN-00
201
GENEVE ZURICH 01-JAN-00
10.
Donnez les
renseignements concernant les trajets effectués avant le 31.12.2000 et dont le
nombre de kilomètres est supérieur à 150 ou inférieur à 100.
SQL>
1 SELECT * FROM trajet
2 WHERE (datetrajet < '31-DEC-00')
3*
AND ( nbkm > 150 OR nbkm < 100 )
4 /
NOTRAJ VILLEDEP
VILLEARR
DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
101
GENEVE ZURICH 01-JAN-00 180
102
GENEVE LAUSANNE 15-FEB-00 60
108
LAUSANNE BERN 20-AUG-00 60
201
GENEVE ZURICH 01-JAN-00 180
202 GENEVE LAUSANNE 16-FEB-00 60
208
LAUSANNE BERN 29-AUG-00 60
6 rows selected.
11.
Donnez les
renseignements concernant les trajets qui soit partant de Lausanne et sont de
moins de
SQL>
1 SELECT * FROM trajet
2 WHERE (villedep = '
3* OR (villearr = '
SQL> /
NOTRAJ VILLEDEP
VILLEARR
DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
103
GENEVE BERN 10-APR-00 120
108
LAUSANNE BERN 20-AUG-00 60
203
GENEVE BERN 19-APR-00 120
208
LAUSANNE BERN 29-AUG-00 60
12.
Affichez le
nombre moyen, le nombre minimum, le nombre maximum de kilomètres des trajets
qui sont arrivés à Bern?
SQL>
1 SELECT AVG(nbkm), MIN(nbkm), MAX(nbkm) FROM
trajet
2* WHERE villearr = 'BERN'
SQL> /
AVG(NBKM)
MIN(NBKM) MAX(NBKM)
---------- ---------- ----------
90 60 120
13.
Affichez
tous les numéros des voitures qui ont été réparées au moins deux fois.
SQL>
1 SELECT nov, COUNT(norep) FROM reparation
2 GROUP BY nov
3* HAVING COUNT(norep) >= 2
SQL> /
NOV
COUNT(NOREP)
------------ ------------
11
3
12
2
14.
Affichez
par ordre croissant tous les numéros des voitures qui ont été réparées dont le
montant moyen est supérieur à 2000.
SQL>
1 SELECT nov, AVG(px) FROM
reparation
2 GROUP BY nov
3* HAVING AVG(px) > 2000
SQL> /
NOV
AVG(PX)
------------ ----------
11
4066.66667
12
6000
15.
Affichez
par ordre croissant tous les numéros des voitures qui n’ont pas été réparées.
SQL>
1 SELECT nov FROM voiture
2 WHERE voiture.nov NOT IN (SELECT reparation.nov
FROM reparation)
3* ORDER BY nov
SQL> /
NOV
------------
13
14
16.
Quel est le
nombre des voitures réparées par chaque garage ?
SQL>
1 SELECT nog, COUNT(DISTINCT nov) FROM
reparation
2* GROUP BY nog
SQL> /
NOG COUNT(DISTINCTNOV)
---------- ------------------
901 1
902 2
903 1
17.
Pour chaque
ville de départ, donner le moyen, le maximum, et le minimum de nombres de
kilomètres effectués par des trajets.
SQL>
1
SELECT villedep, AVG(nbkm), MAX(nbkm), MIN(nbkm)FROM trajet
2* GROUP BY villedep
SQL> /
VILLEDEP AVG(NBKM) MAX(NBKM)
MIN(NBKM)
-------------------- ---------- ---------- ----------
BERN 120 120 120
GENEVE 120 180 60
LAUSANNE 90 120 60
18.
Affichez
les voitures qui ont été réparées au moins trois fois et dont la moyenne des
montants des réparations est supérieure à 3000.
SQL>
1 SELECT nov FROM reparation
2 GROUP BY nov
3 HAVING (COUNT(norep) >= 3) AND (AVG(px) > 3000)
SQL> /
NOV
------------
11
19.
Affichez
les chauffeurs qui ont participé au moins à 4 trajets.
SQL>
1 SELECT nch, COUNT(notraj)
2 FROM tr_nov
3 GROUP BY nch
4* HAVING COUNT(notraj) >= 4
SQL> /
NCH
COUNT(NOTRAJ)
---------- -------------
1 4
2 4
3 5
20.
Quel est le
total moyen des nombres de kilomètres de tous les trajets pendant l’année
2000 ?
SQL>
1 SELECT AVG(nbkm)
2 FROM trajet
3* WHERE datetrajet BETWEEN '01-JAN-00' AND
'31-DEC-00'
4 /
AVG(NBKM)
----------
106.666667
21.
Donnez la
liste de tous les trajets dont la distance est supérieure à la distance du
trajet numéro 208.
SQL>
1 SELECT * FROM trajet
2 WHERE nbkm >
3 (SELECT nbkm FROM trajet
4* WHERE notraj = 208)
SQL> /
NOTRAJ
VILLEDEP VILLEARR DATETRAJE NBKM
---------- -------------------- --------------------
--------- ----------
101
GENEVE
103
GENEVE
109 LAUSANNE ZURICH 20-AUG-00 120
110
LAUSANNE ZURICH 02-JAN-01 120
201 GENEVE
203
GENEVE
209
7 rows selected.
1.
Affichez les numéros et les
marques de toutes les voitures qui ont été réparées et dont le montant de la
réparation est entre 3000 et 5000; affichez aussi leur nombre de kilomètres
parcourus.
SQL>
1 SELECT DISTINCT voiture.nov, mv, km
2 FROM voiture, reparation
3 WHERE (voiture.nov = reparation.nov) AND
4* (px BETWEEN 3000 AND 5000)
NOV
MV KM
------------ -------------------- ----------
11
HONDA 5600
2.
Affichez tous les numéros et
les marques des voitures qui ont été conduites par les chauffeurs LOULOU et
NOUNOU; affichez les par ordre décroissant des numéros.
SQL>
1 SELECT DISTINCT voiture.nov, mv
2 FROM voiture, ch , v_ch
3 WHERE (voiture.nov = v_ch.nov) AND
4 (ch.nch = v_ch.nch) AND
5
(TRIM(chauffeur) IN ('NOUNOU','LOULOU'))
6*
ORDER BY voiture.nov DESC
NOV MV
------------ --------------------
13 HONDA
12 FORD
11 HONDA
3.
Affichez tous les numéros et
les marques des voitures qui ont été réparées et dont la moyenne des montants
des réparations est entre 3000 et 4000.
SQL>
1 SELECT DISTINCT voiture.nov, mv
2 FROM voiture
3 WHERE voiture.nov IN
4 (SELECT
reparation.nov
5 FROM reparation
6 GROUP BY
reparation.nov
7* HAVING AVG(px)
BETWEEN 3000 AND 4000)
no rows selected
4.
Affichez les numéros et les
nombres de kilomètres parcourus de toutes les voitures qui ont été réparées au
moins deux fois.
SQL>
1 SELECT DISTINCT voiture.nov, km
2 FROM voiture
3 WHERE
voiture.nov IN
4 (SELECT reparation.nov
5 FROM reparation
6 GROUP BY reparation.nov
7* HAVING COUNT(norep) >= 2 )
NOV
KM
------------ ----------
11
5600
12
4000
5.
Affichez tous les numéros et
les noms des chauffeurs qui ont
participé au moins à 3 trajets pendant les années 1999 et 2000.
SQL>
1 SELECT ch.nch, chauffeur
2 FROM ch
3 WHERE ch.nch IN
4 ( SELECT tr_nov.nch
5 FROM tr_nov, trajet
6 WHERE (tr_nov.notraj =
trajet.notraj) AND
7 (datetrajet BETWEEN
'01-JAN-99' AND '31-DEC-00')
8 GROUP BY tr_nov.nch
9* HAVING COUNT(tr_nov.notraj)
>= 3 )
NCH CHAUFFEUR
---------- ----------------------------------------
1 BOUBOU
2 LOULOU
3 NOUNOU
6.
Affichez toutes les informations
de la voiture qui a effectué le plus de trajets.
SQL>
1 SELECT * FROM voiture
2 WHERE voiture.nov IN
3 ( SELECT tv1.nov
4 FROM tr_nov tv1
5 GROUP BY tv1.nov
6 HAVING COUNT(tv1.notraj) >=
7 ( SELECT MAX(COUNT(tv2.notraj))
8 FROM tr_nov tv2
9* GROUP BY tv2.nov ))
NOV
MV
KM PSG
------------ -------------------- ---------- ----------
13
HONDA 290 5
7.
Donnez les numéros, les
villes de départ et les villes d’arrivée des trajets qu’ont effectué les
voitures de marque HONDA.
SQL>
1 SELECT DISTINCT trajet.notraj, villedep,
villearr
2 FROM trajet, tr_nov, v_ch, voiture
3 WHERE
(trajet.notraj =
tr_nov.notraj) AND
4
(tr_nov.nov = v_ch.nov) AND (tr_nov.nch = v_ch.nch) AND
5* (v_ch.nov = voiture.nov) AND (mv='HONDA')
NOTRAJ VILLEDEP VILLEARR
---------- -------------------- --------------------
101
GENEVE ZURICH
102
GENEVE LAUSANNE
108
LAUSANNE BERN
110
LAUSANNE ZURICH
201
GENEVE ZURICH
202
GENEVE LAUSANNE
208
LAUSANNE BERN
209 BERN
GENEVE
8 rows selected.
8.
Donnez les numéros, les
villes de départ et les villes d’arrivée des trajets qui, soit ont été assurés
par le chauffeur LOULOU, soit sont arrivés à Lausanne.
SQL>
1 SELECT DISTINCT trajet.notraj, villedep,
villearr
2 FROM trajet, tr_nov, v_ch, ch
3 WHERE
(trajet.notraj = tr_nov.notraj) AND
4 (tr_nov.nov = v_ch.nov)
AND (tr_nov.nch = v_ch.nch) AND
5 (v_ch.nch = ch.nch) AND
6* ((chauffeur = 'LOULOU') OR
(villearr = 'LAUSANNE'))
NOTRAJ
VILLEDEP VILLEARR
---------- -------------------- --------------------
101
GENEVE ZURICH
102
GENEVE LAUSANNE
103 GENEVE BERN
202
GENEVE LAUSANNE
203
GENEVE BERN
209
BERN GENEVE
9.
Donnez la liste de toutes
les voitures (avec leur numéro et leur marque) dont le nombre de kilomètres est
supérieur au nombre de kilomètres de la voiture numéro 13.
SQL>
1 SELECT v1.nov, v1.mv
2 FROM voiture v1 , voiture v2
3 WHERE
(v1.km > v2.km) AND
4*
(v2.nov = 13 )
NOV MV
------------ --------------------
11 HONDA
12 FORD
10.
Donnez tous les numéros et
les noms des chauffeurs qui ont conduit
les trajets dont la voiture a été réparée par la réparation de numéro 554.
SQL>
1 SELECT DISTINCT ch.nch, chauffeur
2 FROM ch, v_ch, tr_nov, voiture,
reparation
3 WHERE
4 (ch.nch = v_ch.nch) AND
5 (tr_nov.nov = v_ch.nov) AND (tr_nov.nch =
v_ch.nch) AND
6 (v_ch.nov = voiture.nov) AND
7* (voiture.nov = reparation.nov) AND (norep =
554)
NCH CHAUFFEUR
---------- ----------------------------------------
2 LOULOU
11.
Affichez tous les numéros et
les noms des chauffeurs qui ont conduit la voiture 11 au moins deux fois
pendant l’année 2000.
SQL>
1 SELECT ch.nch , chauffeur
2 FROM ch
3 WHERE
ch.nch IN
4 ( SELECT tr_nov.nch FROM tr_nov , trajet
5 WHERE (tr_nov.notraj =
trajet.notraj)
6 AND (datetrajet BETWEEN
'01-JAN-00' AND '31-DEC-00')
7 AND (tr_nov.nov = 11)
8 GROUP BY tr_nov.nch
9* HAVING COUNT(tr_nov.notraj) >=
2 )
NCH CHAUFFEUR
---------- ----------------------------------------
1 BOUBOU
12.
Donnez la liste des numéros
des voitures, qui ont fait des trajets à partir de Lausanne de plus de
SQL>
1 SELECT DISTINCT voiture.nov, norep, nog, px
2 FROM trajet, tr_nov, v_ch, voiture,
reparation
3 WHERE
4 (trajet.notraj = tr_nov.notraj) AND
5 (tr_nov.nov = v_ch.nov) AND (tr_nov.nch
= v_ch.nch) AND
6 (v_ch.nov = voiture.nov) AND
7 (villedep = '
8* (voiture.nov = reparation.nov (+))
NOV
NOREP NOG PX
------------ ---------- ---------- ----------
13
14
13.
Donnez la liste des numéros
des voitures qui n’ont pas encore fait des trajets pendant l’année 2001.
SQL>
1 SELECT voiture.nov
2
FROM voiture
3 MINUS
4 SELECT DISTINCT tr_nov.nov
5 FROM trajet, tr_nov
6 WHERE
7 (trajet.notraj = tr_nov.notraj) AND
8* (datetrajet BETWEEN '01-JAN-01' AND
'31-DEC-01')
NOV
------------
14
14.
Donnez la liste des numéros
des chauffeurs, avec leur total des distances (en kilomètres) des trajets effectués.
SQL>
1 SELECT DISTINCT ch.nch, SUM(nbkm)
2 FROM ch, tr_nov, trajet
3 WHERE
4 (ch.nch = tr_nov.nch (+)) AND
5 (tr_nov.notraj
= trajet.notraj (+))
6* GROUP BY
ch.nch
NCH SUM(NBKM)
---------- ----------
1 420
2 540
3 540
4 120
15.
Donnez la liste des numéros
des voitures, avec leur moyenne des montants des réparations.
SQL>
1 SELECT DISTINCT voiture.nov, AVG(px)
2 FROM voiture, reparation
3 WHERE
4 (voiture.nov = reparation.nov (+))
5* GROUP BY voiture.nov
NOV
AVG(PX)
------------ ----------
11
4066.66667
12
6000
13
14
[Bodart 83] F. BODART, Y. PIGNEUR, « Conception assistée des applications
informatiques", Masson, Paris 1983.
[Booch 99] G. Booch, J. Rumbaugh, I. Jacobson, “The UML reference manual”, G. Booch, J.
Rumbaugh, I. Jacobson, Addison-Wesley, 1999.
[Delobel 73] Claude
DELOBEL, « Contribution théoriques à la conception et
l'évaluation d'un système d'informations appliqué à la gestion», Thèse de doctorat, Uni. de Grenoble, Octobre 1973.
[Léonard 88] Michel
LEONARD, « Structures des bases de données »,
Dunod, 1988.
[Léonard 92] Michel LEONARD, “Database
Design Theory”, MacMillan Education Ltd, 1992.
[Rolland 82] C. Rolland, C. Richard, “The REMORA
Methodology for Information Systems Design and Management”, in IFIP WG8.1
Working Conf on IS Design Methodologies: A Comparative Review, North-Holland,
1982.
[Tardieu 83] H. Tardieu, A. Rochfeld, and R. Colletti.,
“La methode MERISE: principes
et outils », Les
Editions d'Organisation, Paris (France), 1983.
[Lano 96]
K. LANO., “The B Language and Method”, Springer Verlag, 1996.
[Date 97] C. J. DATE, H. DARWEN., “A Guide to the SQL Standard”, Addison-Wesley 1997.
[1] Au sens large : institution, administration publique ou privée, association…
[2] Ce chapitre ne fait aucune différence entre transaction et processus : généralement une transaction est considérée comme un processus élémentaire.
[3] Un attribut A de C est obligatoire, si tout
objet de C prend une valeur claire
(non obscure) pour lui. S’il n’est pas obligatoire, on le note A-.
[4] A est un attribut permanent de C si l’on ne peut modifier les valeurs prises par un objet de C pour A : on le note A=.
[5] A est un attribut monovalué de C si un objet de C peut prendre une seule valeur pour A ; s’il peut en prendre plusieurs, A est multivalué : on le note alors A*.