---
marp: true
theme: catppuccin
paginate: true
size: 4:3
transition: coverflow
footer: ''
math: katex
lang: "fr"
---

<style>
section {
  font-size: 28px;
  text-align: left
}
</style>

# Bases de données - Modélisation

---

## Modélisation

Qu'est-ce que la modélisation ?
- **Analyse** et **conception** des informations
- **Représentation** de la structure des informations

Objectif :
- Identifier les **éléments** (entités) logiques
- Identifier et tracer les **dépendances** (relations) logiques entre les entités

C'est une représentation **abstraite** : on ignore les données individuelles elles-mêmes au profit de la structure

---

### Méthode Merise

- Méthodologie de modélisation française assez ancienne (années 70/80)
- Mais éprouvée et toujours d'actualité
- Propose plusieurs étapes sous forme de schémas
    - Dictionnaire de données
    - **MCD** : Modèle Conceptuel de Données
    - **MLD** : Modèle Logique de Données
    - **MPD** : Modèle Physique de Données
    - **LDD** : Langage de définition de données
---

#### Dictionnaire de données

- Document utilisé pour lister les informations à stocker en base
- Obtenu suite à l'analyse des besoins du client
- Simple et compréhensible de tout le monde

---

#### MCD - Modèle Conceptuel de Données

- Schéma utilisé pour représenter les données extraites du dictionnaire
- Regroupe par **entités** et montre les **associations** (relations)
- Reste compréhensible de tout le monde (pas de détails techniques)
- Important car la suite dépend de lui

---

#### MLD - Modèle Logique de Données

- Schéma qui découle directement du MCD
- Ajoute des détails techniques : 
  - Découpage en **tables** et **colonnes**
  - **Clés**
  - **Tables de jointure**

---

#### MPD - Modèle Physique de Données

- Schéma qui représente les données de manière physique
  - Tient compte des spécificités du **SGBD**
  - Ajoute les **types** de données, les **index**, les **contraintes**...

- SGBD = Système de Gestion de Bases de Données
  - Logiciel dédié à la gestion et manipulation des données

---

#### LDD - Langage de définition de données

- Il s'agit de la création des tables sous forme de commandes SQL

---

## Merise en détails

---

<style scoped>
section {
  font-size: 22px;
  text-align: left
}
</style>


### Demande du client

Une loueur de véhicules souhaite construire une base de données pour 
- Enregistrer les véhicules que ses client peuvent louer et les dates de location.
- Il veut pouvoir les joindre facilement, donc il voudra leurs noms et prénoms, ainsi qu'un numéro de téléphone. 
- La loi l'oblige également à stocker le numéro du permis de conduire des conducteurs et conductrices, en cas d'infraction du code de la route. 
- Par ailleurs, il souhaite savoir quel est le kilométrage des véhicules en sa possession, et leur prix journalier
- Pour finir, il veut stocker certaines informations sur les modèles qu'il a en stock pour aider les clients à choisir un véhicule (marque et modèle, nombre de places, type de véhicule, volume pour les utilitaires...)

---

### Le dictionnaire de données

- Document qui contient les informations sur les données à stocker
- Tiré des informations données par le client
- À valider avec le client -> il doit le comprendre
- Informations du dictionnaire de données
  - Nom
  - Format
  - Longueur
  - Contraintes
  - Document (le "groupe" de données)

---

#### Les formats

- **Alphabétique** 
  - A-Z uniquement
- **Alphanumérique** 
  - A-Z et 0-9, éventuellement caractères spéciaux
- **Numérique**
  - Nombres entiers, flottants etc..
- **Date**
- **Logique**
  - Vrai/Faux

---

#### Les contraintes

Ce sont les contraintes du client
- Données **obligatoires**
- Données **uniques**
- Valeurs par défaut
- Etc.

---

<style scoped>
table {
  font-size: 22px;
  text-align: left
}
</style>

#### Dans notre exemple

**Document** : Conducteur

| Nom                          | Format         | Longueur | Contrainte          |
| ---------------------------- | -------------- | -------- | ------------------- |
| Nom                          | Alphabétique   | 30       | Obligatoire         |
| Prénom                       | Alphabétique   | 30       | Obligatoire         |
| Numéro de téléphone          | Alphanumérique | 20       | Obligatoire         |
| Numéro de permis de conduire | Alphanumérique | 50       | Obligatoire, Unique |

---
<style scoped>
table {
  font-size: 22px;
  text-align: left
}
</style>
**Document** : Véhicule

| Nom             | Format         | Longueur | Contrainte          |
| --------------- | -------------- | -------- | ------------------- |
| Immatriculation | Alphanumérique | 30       | Obligatoire, Unique |
| Kilométrage     | Numérique      | -        | Obligatoire         |
| Prix journalier | Numérique      | -        | Obligatoire         |

---
<style scoped>
table {
  font-size: 22px;
  text-align: left
}
</style>
**Document** : Modèle

| Nom              | Format         | Longueur | Contrainte                       |
| ---------------- | -------------- | -------- | -------------------------------- |
| Marque           | Alphanumérique | 30       | Obligatoire                      |
| Modèle           | Alphanumérique | 30       | Obligatoire                      |
| Nombre de places | Numérique      | -        | Obligatoire                      |
| Volume           | Numérique      | -        | Obligatoire pour les utilitaires |
| Type de véhicule | Alphabétique   | 30       |                                  |

L'association marque-modèle est unique (pour simplifier l'exemple)

---
<style scoped>
table {
  font-size: 22px;
  text-align: left
}
</style>
**Document** : Location

| Nom           | Format | Longueur | Contrainte  |
| ------------- | ------ | -------- | ----------- |
| Date de début | Date   | -        | Obligatoire |
| Date de fin   | Date   | -        | Obligatoire |

---

### MCD - Le Modèle Conceptuel de Données

- Représenter les données récupérées dans le dictionnaire
- Doit rester compréhensible par le client

---

#### Le diagramme

![MCD base](images/mcd-base.png)

---

#### Vocabulaire

- Le diagramme possède des **entités** 
  - carrés jaunes
- qui sont composées d'**attributs**
  - certains attributs peuvent être **uniques**
  - écrit en gras
    - leur valeur ne peut se retrouver qu'une seule fois
  - certains attributs peuvent être **discriminants**
    - écrit en gras et souligné
    - ils **identifient** de manière unique une occurrence

---

- Le diagramme possède des **associations**
  - Bulle ovale
  - Représentée par un **verbe à l'infinitif**
- Les associations ont une **cardinalité**
  - Nombre d'occurrences d'une entité par rapport à une autre

---

#### Les cardinalités

- Élément essentiel du MCD
- Définit le nombre d'occurrences d'une entité par rapport à une autre (l'entité est associée à X occurrences)
- Cardinalité est définie par deux valeurs :
  - **Minimum** d'occurrences
  - **Maximum** d'occurrences
  - On l'écrit sous forme : **Min,Max**

---

- Valeurs courantes :
  - **0** : signifie "0 occurrence"
  - **1** : signifie "1 occurrence"
  - **N** : signifie "n'importe quel nombre d'occurrences"
- Cardinalités courantes : (l'entité est associée à)
  - **0,1** : Soit aucune soit une occurrence
  - **1,1** : Exactement 1 occurrence
  - **0,n** : N'importe quel nombre d'occurrences
  - **1,n** : Au moins une occurrence

---

#### Associations réflexives

- Certaines entités peuvent être reliées à elles-mêmes par une association
  - Ce sont des **associations réflexives**
- **Exemple** : Genres de livres
  - Un genre peut regouper des sous-genres plus précis
  - On crée une association réflexive entre l'entité "Genre" et elle-même
  - Crée une hiérarchie de genres

---

#### Héritage

**L'héritage** va nous permettre de rassembler des propriétés identiques dans une entité commune (appelée **entitée générique**) et créer des entités plus spécialisées appelées **entitées spécialisées**

![heritage](images/heritage.png)

---

#### Dans notre exemple

![mcd height:600px](images/mcd.png)

---

<style scoped>
section {
  font-size: 22px;
  text-align: left
}
</style>
#### Choix du discriminant

- Attributs peuvent identifier de manière unique un enregistrement
  - **Discriminant naturel**
    - Attribut appartenant à l'objet qui identifie de manière unique
       -  ex: numéro de sécurité sociale
  - **Discriminant synthétique**
    - Attribut créé de toutes pièces pour identifier l'objet

- Préférer un discriminant synthétique
  - Facilite la maintenance
  - Facilite les changements plus tard
  - Réduit le nombre de modifications quand on change le discriminant

---

![mcd height:600px](images/mcd-id.png)

--- 

### MLD - Le Modèle Logique de Données

- Le MLD est la suite logique et directe du MCD
- Il en découle directement par l'application de règles simples
- Transforme le MCD en modèle qui peut être implémenté dans un SGBD
- Ajoute des détails techniques

---

#### Convertir les entités et attributs

- Les **entités** deviennent des **tables**
- Les **attributs discriminants** (gras soulignés) deviennent des **clés primaires**
  - Clé primaire : donnée (composée d'une ou plusieurs colonnes) qui permet d'identifier de manière unique un enregistrement dans une table
- Les **attributs uniques** (gras) deviennent des **colonnes uniques**
- Les autres **attributs** deviennent des **colonnes**

---

#### Convertir les associations

Il faut se baser sur la cardinalité de chaque association.

2 cas possibles (x vaut 0 ou 1) :
- (x, n) - (x, 1) : Many to One / One to Many
- (x, n) - (x, n) : Many to Many

---

##### Many to One - (x, n) - (x, 1)

!!! success La règle
- On ajoute une **clé étrangère** dans la table du côté de la relation **One** (x, 1)
!!!

- La clé étrangère est la clé primaire de la table côté **Many**
  - Elle vient servir de référence à un enregistrement
- L'**héritage** entre dans ce cas :
  - On considère qu'une entité spécialisée peut spécialiser exactement 1 entité générique (1,1)
  - Une entité générique peut être spécialisée par n entités spécialisées (0,n)
  - On est dans une relation (0,n) - (1,1)

---

###### Exemple Many to One

| MCD                                          | MLD                                            |
| -------------------------------------------- | ---------------------------------------------- |
| ![manytoone_mcd](images/many-to-one-mcd.png) | ![many to one mld](images/many-to-one-mld.png) |

---

###### Exemple héritage

| MCD                                                  | MLD                                                  |
| ---------------------------------------------------- | ---------------------------------------------------- |
| ![heritage mcd width:400px](images/heritage-mcd.png) | ![heritage mld width:400px](images/heritage-mld.png) |
---

##### Many to Many

- Dans ce cas impossible de stocker une clé étrangère dans l'une des deux tables : il faudrait pouvoir stocker des listes de clés.

!!! success La règle
On crée une **table de jointure** qui va relier les deux tables
!!!

- **Nom** : composé des deux tables qu'elle relie, avec le nom de l'association netre deux : `entity1_action_entity2`
- **Colonnes** : Clés étrangères des deux tables qu'elle relie + autres colonnes de la relation

---

###### Exemple 

![Many to Many width:800px](images/manytomany-mcd.png)
![Many to Many MLD width:800px](images/manytomany-mld.png)

---

##### Associations réflexives

Dans ce cas on applique exactement les mêmes règles :
- Si la relation est **Many to One** : on ajoute une **clé étrangère**
  - qui sera la clé primaire de la même table
- Si la relation est **Many to Many** : on ajoute une **table de jointure**
  - qui contiendra des clés primaires de la table
---
###### Exemple association réflexive Many to One
![reflexive-mcd](images/reflexive-mcd.png)
![reflexive-mld](images/reflexive-mld.png)

---
###### Exemple association réflexive Many to Many
![reflexive-many-mcd](images/reflexive-many-mcd.png)
![relflexive-many-mld](images/reflexive-many-mld.png)

---

##### Associations avec plus de deux tables

!!! success La règle
On crée une **table de jointure** qui va relier toutes les tables
!!!

| MCD                                         | MLD                                       |
| ------------------------------------------- | ----------------------------------------- |
|![ternaire-mcd width:400px](images/ternaire-mcd.png)|![ternaire-mld width:400px](images/ternaire-mld.png)|

---

##### Cas particuliers 

- (0, 1) - (1, 1) : On utilisera une **clé étrangère** 
  - Comme si c'était une relation Many to One où n = 1
- (1, 1) - (1, 1) : Ce type de relation n'a pas de sens
  - Si cela arrive c'est que vous avez découpé en deux entités ce qui aurait dû n'en faire qu'une

---

#### Dans notre exemple 

| MCD                                         | MLD                                       |
| ------------------------------------------- | ----------------------------------------- |
| ![ex-mcd2 height:550px](images/ex-mcd2.png) | ![ex-mld height:550px](images/ex-mld.png) |

---

## MPD - Modèle Physique de données

---

- Dernière étape : ajoute les détails techniques pour implémenter le modèle dans le SGBD
- Détails techniques :
  - Types de données
  - Taille des colonnes
  - Contraintes d'intégrité
  - Clés étrangères

- C'est à ce stade qu'on va tenir compte des spécificités de chaque SGBD

---

![mpd height:600px](images/mpd.png)

---

## LDD - Langage de Définition de Données

---

```sql
CREATE TABLE IF NOT EXISTS "louer" (
	"id_location" UUID NOT NULL,
	"identifiant_conducteur" UUID NOT NULL UNIQUE,
	"identifiant_vehicule" UUID NOT NULL,
	"debut" DATE NOT NULL,
	"fin" DATE NOT NULL,
	PRIMARY KEY("id_location")
);

CREATE TABLE IF NOT EXISTS "conducteur" (
	"identifiant_conducteur" UUID NOT NULL UNIQUE,
	"nom" VARCHAR(255) NOT NULL,
	"prenom" VARCHAR(255) NOT NULL,
	"numero_de_telephone" VARCHAR(255) NOT NULL,
	"numero_de_permis_de_conduire" VARCHAR(255) NOT NULL,
	PRIMARY KEY("identifiant_conducteur")
);

CREATE TABLE IF NOT EXISTS "vehicule" (
	"identifiant_vehicule" UUID NOT NULL UNIQUE,
	"immatriculation" VARCHAR(255) NOT NULL,
	"kilometrage" INTEGER NOT NULL,
	"prix_journalier" DOUBLE PRECISION NOT NULL,
	"identifiant_modele" UUID NOT NULL,
	PRIMARY KEY("identifiant_vehicule")
);
```
---
```sql
CREATE TABLE IF NOT EXISTS "modele" (
	"identifiant_modele" UUID NOT NULL UNIQUE,
	"marque" VARCHAR(255) NOT NULL,
	"modele" VARCHAR(255) NOT NULL,
	"nombre_de_places" SMALLINT NOT NULL,
	PRIMARY KEY("identifiant_modele")
);
CREATE TABLE IF NOT EXISTS "utilitaire" (
	"id_utilitaire" UUID NOT NULL UNIQUE,
	"volume" DOUBLE PRECISION NOT NULL,
	PRIMARY KEY("id_utilitaire")
) INHERITS ("modele");

CREATE TABLE IF NOT EXISTS "vehicule_de_tourisme" (
	"id_vehicule_de_tourisme" UUID NOT NULL UNIQUE,
	PRIMARY KEY("id_vehicule_de_tourisme")
) INHERITS ("modele");

ALTER TABLE "louer"
ADD FOREIGN KEY("identifiant_conducteur") REFERENCES "conducteur"("identifiant_conducteur")
ON UPDATE NO ACTION ON DELETE NO ACTION;
ALTER TABLE "louer"
ADD FOREIGN KEY("identifiant_vehicule") REFERENCES "vehicule"("identifiant_vehicule")
ON UPDATE NO ACTION ON DELETE NO ACTION;
ALTER TABLE "modele"
ADD FOREIGN KEY("identifiant_modele") REFERENCES "vehicule"("identifiant_modele")
ON UPDATE NO ACTION ON DELETE NO ACTION;
```
