....
Considérons une activité : l'emprunt d’un livre dans une médiathèque municipale.
Alice trouve le livre qu’elle souhaite emprunter et approche d’une borne d'emprunt automatique. Elle scanne le code barre de sa carte de bibliothèque et des informations la concernant apparaissent :
« Alice, aucun livre en cours de prêt ».
Elle peut ensuite scanner le code barre apposé sur le livre. Les informations sont alors mises à jour pour afficher la liste des livres empruntés :
« La Programmation en pratique, B. Kernighan et R. Pike, Ed. Vuibert, 2017, ISBN 978-2711786701 ».
Sur la borne d’à côté, Basile vient rendre ses livres. Il scanne lui aussi sa carte et les informations le concernant apparaissent à l'écran :
« Basile, un livre en cours de prêt ».
Basile peut alors scanner le code barre du livre qu’il rapporte et ce dernier est supprimé de la liste.
Cette simple activité nous permet d'illustrer les caractéristiques d’un système d’information, c’est-à-dire d'un système technique (ici informatique) et humain permettant de gérer de l'information.
Que pouvons-nous dire sur le système informatique sous-jacent ?
En premier lieu, il contient une description d’objets (les livres), de personnes physiques (les usagers) et des
processus (l'emprunt et la restitution de livres).
Le système ne contient cependant qu’une «approximation» de la réalité :
En effet, il ne retient pour Alice et Basile que leur nom et prénom, éventuellement leur date d’inscription et
les livres en cours d'emprunt ;
Nous pourrions rajouter d’autres informations telle que :
- leur taille,
- la couleur de leurs yeux
- ou leur plat préféré ne sont pas connus du système.
******
De même pour les livres seuls le titre, les auteurs, l'éditeur et l'ISRN [le
Les clés primaires ne permettent pas seulement
de distinguer les entités de manière unique.
Elles permettent aussi de servir de référence dans une autre relation.
Intéressons nous maintenant à la relation Emprunt. L'exemple que l’on a donné en introduction est naïf, car
il stocke dans cette table le prénom de l'utilisateur, le titre du livre et la date de rendu.
On pourra plutôt définir la relation Emprunt avec le schéma suivant :
Emprunt(code_barre ; String, isbn : String, retour : Date)
Ici, code_barre et isbn sont des clés étrangères.
Cela signifie que la valeur de l’attribut code _barre dans la relation Emprunt doit être l’une des valeurs existantes pour cet attribut dans la relation Usager.
De même, isbn doit correspondre à un isbn existant dans la relation Livre. Cette contrainte permet de garantir que la relation Emprunt ne mentionne que des livres et des usagers connus de la base de données.
Elle permet d'éviter de rajouter des valeurs fictives ne correspondant à aucun utilisateur ou à aucun livre.
De manière plus importante, elle empêche aussi de supprimer des entités des relations Livre et Usager. En particulier, si la relation Emprunt contient l’entité
(\"123456789\", \"978-2340033641\", 07/03/2020),
alors retirer l’utilisateur dont le code barre est \"23456789\" de la relation Usager est une violation de la contrainte de référence, car la valeur \"123456789\" ne
serait plus celle d’une clé primaire dans la relation Usager (et d'un point de vue pratique, cela permet de s'assurer qu'avant de désinscrire une personne, cette dernière a rendu tous ses livres).
Une autre remarque que l’on peut faire sur le schéma Emprunt est que l’isbn est déclaré comme clé primaire de la relation. Cela implique qu’un même livre ne peut apparaître dans deux entités distinctes. Là encore, on
voit que la contrainte nous permet de garantir la cohérence des données :
il n’est pas possible qu’un même livre soit emprunté par deux usagers en même temps.
Une dernière observation importante sur l’utilisation des clés étrangères est qu'elle permet de créer des associations multiples entre entités de différentes relations.
Ici, on peut associer au même utilisateur plusieurs livres
en cours d'emprunt. En effet, code_barre n'étant qu’une clé étrangère, il n’a pas à être unique dans la relation Emprunt :
un même utilisateur a le droit d’emprunter plusieurs livres. En d’autres termes, nous pouvons par ce moyen associer à un utilisateur une liste de livres.
Nous pouvons utiliser cette technique pour pallier un défaut de conception de la relation Livre.
En effet, dans cette dernière, nous avons représenté les auteurs du livre comme un chaîne de caractères dans laquelle est écrite la liste des auteurs.
Bien que cette modélisation fonctionne, elle ne permet pas d'exprimer certaines contraintes sur les données, par exemple qu’un même auteur n’apparaît pas deux fois pour le même livre.
En effet. les chaînes de caractères étant arbitraires, on peut y saisir n'importe quoi. L'utilisation de clés étrangères va nous permettre de remédier à ce problème. On simplifie dans un premier temps le schéma de la relation Livre pour ne plus mentionner les auteurs :
Livre(titre : String, éditeur : String, année : Int, isbn : String)
On peut ensuite créer une nouvelle relation, Auteurs ayant le schéma suivant :
Auteur(a_id : Int, nom : String, prénom : String)
Ici, l’attribut a_id est un identifiant d’auteur unique, associé à l’auteur lorsque l'employé de la médiathèque rajoute un nouvel auteur dans la base.
La relation Auteur pourrait par exemple être la suivante :
{ (0, ’Goscinny”,’René’), (10, ’Kernighan’,’Brian’),
(2, ’Conchon’,’Sylvain’), (42, ’Filliâtre’, Jean-Christophe’), (4, ’Pike’,’Rob”’), (19, ’Balabonski”,’Thibaut’), (23, ’Uderzo”,’Albert’), (77, Nguyen’, ’Kim’), ... }
La seule contrainte sur les identifiants est qu’ils doivent être uniques.
Il n’y a en particulier aucune notion d'ordre. Munis des relations Livre et Auteur, nous pouvons associer des auteurs à des livres au moyen de la relation Auteur_ de :
Auteur_de(a_id : Int, isbn : String)
Cette relation associe des auteurs à des livres. Les attributs a_id et isbn sont des clés étrangères faisant référence aux relations Auteur et Livre respectivement.
Le couple de ces deux attributs forment la clé primaire de la table Auteur_de. Cela empêche qu’un même auteur et un même livre apparaissent deux fois dans la relation et donc qu’un même auteur soit mentionné deux fois pour le même ouvrage.
En revanche, rien n'empêche qu’un même auteur apparaisse plusieurs fois pour des ouvrages différents, ou que différents auteurs apparaissent pour le même ouvrage.
Attention cependant, si un isbn n'apparaît pas dans cette relation, c’est que le livre correspondant n’a pas
d'auteur. Les contraintes de clé primaires et étrangères ne permettent pas d'empêcher ce cas de figure.
Nous terminons ce tour d’horizon des contraintes
d’intégrité par les contraintes utilisateurs (parfois appelées contraintes métier).
Ces dernières sont toutes les contraintes d’une relation qu’on ne peut exprimer par les trois précédentes. Un exemple de contrainte utilisateur est qu’un âge de personne doit être positif et inférieur à 200. Pour notre médiathèque, une autre contrainte utilisateur pourrait être que la chaîne de caractères représentant l'e-mail contienne un et un seul caractère « @ ».
Ces contraintes, liées à l’utilisation que l’on veut faire de la base de données,sont importantes mais difficilement exprimables dans la syntaxe très simple
des schémas.
On veillera donc à en faire une description précise en français.
Nous verrons dans la séquence suivant que les systèmes de gestion de bases de données proposent une syntaxe pour écrire certaines de ces contraintes.
Le modèle relationnel est un modèle dans lequel
les données sont représentées par des ensembles de n-uplets appelés des relations.
Un élément d’une relation est appelé une entité. Il représente généralement un objet,
une action, une personne du monde réel.
Chaque entité possède des propriétés appelées des attributs.
On spécifie une relation en donnant son schéma, c’est-à-dire son nom, la liste de ses attributs avec leur domaine, c’est-à-dire l’ensemble des valeurs que peuvent prendre un attribut.
Une base de données est un ensemble de relations et le schéma d’une base est l’ensemble des schémas des
relations qui la compose.
La cohérence des données au sein d’une base est assurée par des
contraintes d’intégrité. Ces dernières sont des invariants, c’est-à-dire
des propriétés logiques que les données doivent vérifier à tout instant.
On distingue parmi ces contraintes :
Les contraintes d’entité qui garantissent que chaque entité d’une relation est unique. Une clé primaire est un ensemble d’attributs qui identifie chaque entité de la relation de manière unique et garantit la contrainte d’entité.
Les contraintes de référence qui créent des associations entre deux relations. Elle permettent de garantir qu’une entité d’une relation B mentionne une entité existante dans une relation A.
Une clé étrangère est un ensemble d’attributs d’une table qui sont une clé primaire dans une autre table.
Les contraintes de domaines qui restreignent les valeurs d’un attribut à celles du domaine et évitent que l’on puisse donner à un attribut une valeur illégale.
Les contraintes utilisateurs qui restreignent encore plus les valeurs d’un ou de plusieurs attributs et sont guidées par la nature des données que l’on souhaite stocker dans la base.
Ces contraintes doivent être utilisées pour assurer la qualité des données :
elles permettent de s'assurer que les données sont « conformes » aux entités du monde réel qu’elles représentent.
","title":" "},{"edit":"Mettre le résultat ici.
On souhaite modéliser un annuaire téléphonique simple dans lequel chaque personne (identifiée par son nom et son prénom) est associée
à son numéro de téléphone.
Proposer une modélisation relationnelle de cet
annuaire.
","title":"Exercice"},{"edit":"Mettre le résultat ici (code et figure).
De façon très simple, on peut modéliser l'annuaire
de la manière suivante :
Annuaire(nom : String, prénom : String, tel :String)
On n’oubliera pas de préciser que le numéro, par définition unique, est une clé primaire. Son domaine peut être String afin d’éviter les problèmes de 0 en première position ou de permettre de saisir des caractères non numériques
comme +.
Donner la modélisation relationnelle d’un bulletin scolaire.
Cette dernière doit permettre de mentionner :
- des élèves, possédants un numéro d'étudiant alphanumérique unique;
- un ensemble de matières fixées, mais qui ne sont pas données;
- au plus une note sur 20, par matière et par élève.
On prendra soin de préciser toutes les contraintes utilisateurs qui ne peuvent êtres inscrites dans les schémas des relations.
","title":"Exercice"},{"edit":"Mettre le résultat ici (code et figure).
La modélisation consiste en trois relations
Eleve(nom String, prénom String, num String)
Matiere(intitule String, m_id INT)
Note(num String, m_id INT, note Float)
On n’a pas moyen de forcer que la valeur de la note soit comprise entre 0 et
20. On à fait le choix de donner un indentifiant numérique à la matière.
On considère la solution donnée pour l'exercice précédent sur l'annuaire.
Dire si chacun des ensembles est une relation valide pour le schéma Annuaire.
Annuaire(nom : String, prénom : String, tel :String)
1. { }
2. {('Titi', 'Toto', '0123456789' )}
3. {( 'Titi', 'Toto’, '0123456789'), (’Doe”, 'John’, '0123466789’ )}
4.{('Titi','Toto', '0123456789'), ('Titi', 'Toto', '987654343210' )}
5. {('Titi', 'Toto', '0123466789'), (’Doe’,’John’)}
6. {('Titi',’Toto’, 42)}
Mettre le résultat ici (code et figure).
1. Oui, la relation vide est un ensemble valide
2. Oui, la relation ne contient qu’un triplet bien formé
3. Non, les deux triplets ont la même valeur pour l’attribut tel qui est une clé primaire.
4. Oui, les deux clés primaires des deux entités sont différentes.
5. Non, l’ensemble contient un couple, qui n’est pas une entité bien formée pour le schéma Annuaire
6. Non, l’ensemble contient un triplet dont la clé primaire est un nombre et non pas une chaîne
On considère la solution donnée pour l'exercice 141. Dire si
chacun des ensembles est une relation valide pour le schéma de la base de
données du bulletin de notes,
1 + Eleve={}
e Matiere = {}
e Note={}
2. e Eleve= {(°Titi’, Toto’, ’AB56789°),}
e Matiere = {(?N51°,0),(’Sport’,1)}}
e Note = {(°AB56789,1,17)}
3 + Eleve = {(’Titi’,’Toto”,’AB56789°),}
e Matiere = {(°NSI’,0)}
+ Note = {(’AB56789°,1,17)}4 + Eleve= {(°Titi’, Toto’, ’AB56789?), }
+ Matiere = {(°NSI’,0),}
+ Note = {(’AB56789°,0,17), (*AB56789°,0,18)}
ox
.
Eleve = {(°Titi’,’Toto?, ’AB56789),}
« Maticre = {(°NSI?,0), (’Sport”’,1}}
+ Note = {(*AB56789°,0,17), (’AB56789?,1,17)}
Solution page 488 0
Mettre le résultat ici (code et figure).
Exercice 144 Modéliser des informations sur les départements français.
Pour chaque département on veut pouvoir stocker son nom, son code, son
chef-lieu et la liste de tous les départements voisins. Attention, les codes de
département sont tous des nombres, sauf la Corse du Sud et la Haute Corse
qui ont les codes 2A et 2B respectivement, Les départements d'Outre-Mer
ont un code sur trois chiffres (de 971 à 976). Proposer une contrainte uti-
lisateur permettant d'éviter la redondance d'information dans la liste des
voisins. Solution page 488 D
Mettre le résultat ici (code et figure).
Exercice 145 Proposer une modélisation pour un réseau de bus. Cette der-
nière doit être suffisamment riche pour permettre de générer, pour chaque
arrêt de bus du réseau, une fiche horaire avec tous les horaires de passage
de toutes les lignes de bus qui desservent l'arrêt.
Indication : ici, plus qu'une simple traduction du français vers le modèle
relationnel, on essayera de déterminer dans un premier temps quelles in-
formations sont pertinentes et comment les représenter. On pourra ensuite
procéder à la modélisation sous forme de relations. Solution page 488 ©
Mettre le résultat ici (code et figure).
Exercice 146 On considère deux relations R(a Int,b Int,c Int) et
S(a Int,e Int) où l’attribut a de S est une clé étrangère faisant référence à
a de À. Dire si les affirmations suivantes sont vraies ou fausses, en justifiant.
1. Les a de À sont tous deux à deux distincts.
Les b de R sont tous deux à deux distincts.
Les a de S sont tous deux à deux distincts.
Les e de S sont tous deux à deux distincts.
S peut être vide alors que R est non vide.
Sp gœ
R peut être vide alors que $ est non vide
Solution page 489 0
","title":"Exercice"},{"edit":"Mettre le résultat ici (code et figure).
Ecrire une fonction qui donne le nombre de jour de chaque mois. On utilisera un tableau pour stocké le nombre de jours de chaque mois.
Exemple :
print(nbjoursmois(2020, 2))
print(nbjoursmois(2020, 4))
Résultat :
29
30
","title":"Exercice"},{"edit":"Mettre le résultat ici (code et figure).
On fait un cas particulier pour le mois de février, puis
on utilise un tableau comme suggéré.
def nbjoursmois(a, m):
if m == 2 and a%4==0 :
return 29
t = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
return t[m - 1]