Compare commits
No commits in common. "200b1c2bfd38f5850183ef280843c87c8caead9c" and "3f1b0fc18a1983db63fb15d6f6f006f50819179e" have entirely different histories.
200b1c2bfd
...
3f1b0fc18a
@ -22,7 +22,9 @@ export async function data(pageContext: PageContext) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let cachePathname = urlParsed.pathname.replace(/\/$/, "").replace(/^\//, "");
|
let cachePathname = urlParsed.pathname.replace(/\/$/, "").replace(/^\//, "");
|
||||||
if (cachePathname === "") cachePathname = "index";
|
if (cachePathname === "") {
|
||||||
|
cachePathname = "index";
|
||||||
|
}
|
||||||
|
|
||||||
const doc = docCache.get(cachePathname);
|
const doc = docCache.get(cachePathname);
|
||||||
|
|
||||||
@ -39,7 +41,7 @@ export async function data(pageContext: PageContext) {
|
|||||||
docs: docCache.orderByLastEdit({
|
docs: docCache.orderByLastEdit({
|
||||||
limit: 2,
|
limit: 2,
|
||||||
includedBasePaths: ["docs", "certifications"],
|
includedBasePaths: ["docs", "certifications"],
|
||||||
excludedFileNames: [cachePathname, "docs", "certifications"],
|
excludedFileNames: [cachePathname],
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,336 +1,87 @@
|
|||||||
import { For } from "solid-js";
|
export default function DictionnaryTable() {
|
||||||
|
|
||||||
type DataTable = {
|
|
||||||
tableName: string;
|
|
||||||
hiddenInBasic?: boolean;
|
|
||||||
documentName: string;
|
|
||||||
columns: DataColumn[];
|
|
||||||
primaryKeys?: string[];
|
|
||||||
foreignKeys?: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type DataColumnType =
|
|
||||||
| "Alphanumérique"
|
|
||||||
| "Alphabétique"
|
|
||||||
| "Numérique"
|
|
||||||
| "Date"
|
|
||||||
| "Logique";
|
|
||||||
|
|
||||||
type DataColumn = {
|
|
||||||
name: string;
|
|
||||||
logical: string;
|
|
||||||
dbmsType: string;
|
|
||||||
dbmsLength?: number;
|
|
||||||
length?: string | number;
|
|
||||||
type: DataColumnType;
|
|
||||||
hiddenInTechnical?: boolean;
|
|
||||||
hiddenInBasic?: boolean;
|
|
||||||
dbmsConstraints: string[];
|
|
||||||
constraints?: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const data: DataTable[] = [
|
|
||||||
{
|
|
||||||
tableName: "musician",
|
|
||||||
documentName: "Musicien",
|
|
||||||
primaryKeys: ["id_musician"],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: "code musicien",
|
|
||||||
logical: "id_musician",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
dbmsConstraints: ["AUTO_INCREMENT", "NOT_NULL", "UNIQUE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Nom",
|
|
||||||
logical: "lastname",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Numérique",
|
|
||||||
length: 30,
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Prénom",
|
|
||||||
logical: "firstname",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Numérique",
|
|
||||||
length: 30,
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Instruments",
|
|
||||||
logical: "instruments",
|
|
||||||
dbmsType: "VARCHAR[]",
|
|
||||||
type: "Alphabétique",
|
|
||||||
length: 30,
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Adresse e-mail",
|
|
||||||
logical: "email",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphanumérique",
|
|
||||||
length: 50,
|
|
||||||
dbmsLength: 50,
|
|
||||||
dbmsConstraints: ["NOT_NULL", "UNIQUE"],
|
|
||||||
constraints: ["Obligatoire", "Unique"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Mot de passe",
|
|
||||||
logical: "password",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphanumérique",
|
|
||||||
length: "> 12",
|
|
||||||
dbmsLength: 32,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "musician_participates_event",
|
|
||||||
documentName: "",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
primaryKeys: ["id_musician", "event_id"],
|
|
||||||
foreignKeys: ["id_musician", "event_id"],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
logical: "event_id",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Lieu",
|
|
||||||
logical: "location",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphabétique",
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Date et heure",
|
|
||||||
logical: "datetime",
|
|
||||||
dbmsType: "TIMESTAMPZ",
|
|
||||||
type: "Alphabétique",
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "event",
|
|
||||||
documentName: "",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
primaryKeys: ["id_event"],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
logical: "id_event",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
dbmsConstraints: ["AUTO_INCREMENT", "NOT_NULL", "UNIQUE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Lieu",
|
|
||||||
logical: "location",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphabétique",
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Date et heure",
|
|
||||||
logical: "datetime",
|
|
||||||
dbmsType: "TIMESTAMPZ",
|
|
||||||
type: "Alphabétique",
|
|
||||||
dbmsLength: 30,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "concert",
|
|
||||||
documentName: "Concert",
|
|
||||||
primaryKeys: ["id_concert"],
|
|
||||||
foreignKeys: ["event_id"],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: "code concert",
|
|
||||||
logical: "id_concert",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
dbmsConstraints: ["AUTO_INCREMENT", "NOT_NULL", "UNIQUE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Date et heure",
|
|
||||||
logical: "datetime",
|
|
||||||
dbmsType: "TIMESTAMPZ",
|
|
||||||
type: "Date",
|
|
||||||
hiddenInTechnical: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Lieu",
|
|
||||||
logical: "location",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphabétique",
|
|
||||||
hiddenInTechnical: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Tarif",
|
|
||||||
logical: "price",
|
|
||||||
dbmsType: "CURRENCY",
|
|
||||||
type: "Numérique",
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
logical: "event_id",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "rehearsal",
|
|
||||||
documentName: "Répétition",
|
|
||||||
primaryKeys: ["id_rehearsal"],
|
|
||||||
foreignKeys: ["event_id"],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: "code répétition",
|
|
||||||
logical: "id_rehearsal",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
dbmsConstraints: ["AUTO_INCREMENT", "NOT_NULL", "UNIQUE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Date et heure",
|
|
||||||
logical: "datetime",
|
|
||||||
dbmsType: "TIMESTAMPZ",
|
|
||||||
type: "Date",
|
|
||||||
hiddenInTechnical: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Lieu",
|
|
||||||
logical: "location",
|
|
||||||
dbmsType: "VARCHAR",
|
|
||||||
type: "Alphabétique",
|
|
||||||
hiddenInTechnical: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
constraints: ["Obligatoire"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
logical: "event_id",
|
|
||||||
dbmsType: "INTEGER",
|
|
||||||
type: "Numérique",
|
|
||||||
hiddenInBasic: true,
|
|
||||||
dbmsConstraints: ["NOT_NULL"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
type DictionnaryTableProps = {
|
|
||||||
isTechnical?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function DictionnaryTable(props: DictionnaryTableProps) {
|
|
||||||
return (
|
return (
|
||||||
<For
|
|
||||||
each={data.filter((table) => props.isTechnical || !table.hiddenInBasic)}
|
|
||||||
>
|
|
||||||
{(table) => (
|
|
||||||
<table class="block max-w-full overflow-x-auto border-collapse text-sm">
|
<table class="block max-w-full overflow-x-auto border-collapse text-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">
|
<th scope="col">Nom de la donnée</th>
|
||||||
{props.isTechnical ? "Colonne" : "Nom de la donnée"}
|
<th scope="col">Format</th>
|
||||||
</th>
|
|
||||||
<th scope="col">{props.isTechnical ? "Type" : "Format"}</th>
|
|
||||||
<th scope="col">Longueur</th>
|
<th scope="col">Longueur</th>
|
||||||
<th scope="col">Contraintes</th>
|
<th scope="col">Contraintes</th>
|
||||||
|
<th scope="col">Document</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<For
|
|
||||||
each={table.columns.filter((column) =>
|
|
||||||
props.isTechnical
|
|
||||||
? !column.hiddenInTechnical
|
|
||||||
: !column.hiddenInBasic,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{(column) => (
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{props.isTechnical ? column.logical : column.name}</td>
|
<td>Nom</td>
|
||||||
<td>{props.isTechnical ? column.dbmsType : column.type}</td>
|
<td>Alphabétique</td>
|
||||||
<td>
|
<td>30</td>
|
||||||
{props.isTechnical
|
<td>Obligatoire</td>
|
||||||
? column.dbmsLength || "-"
|
<td>Musicien</td>
|
||||||
: column.length || "-"}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
<td>
|
<td>Prénom</td>
|
||||||
{props.isTechnical
|
<td>Alphabétique</td>
|
||||||
? column.dbmsConstraints?.join(", ") || "-"
|
<td>30</td>
|
||||||
: column.constraints?.join(", ") || "-"}
|
<td>Obligatoire</td>
|
||||||
</td>
|
<td>Musicien</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Instruments</td>
|
||||||
|
<td>Alphabétique</td>
|
||||||
|
<td>30</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Musicien</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Adresse e-mail</td>
|
||||||
|
<td>Alphanumérique</td>
|
||||||
|
<td>50</td>
|
||||||
|
<td>Obligatoire, unique</td>
|
||||||
|
<td>Musicien</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mot de passe</td>
|
||||||
|
<td>Alphanumérique</td>
|
||||||
|
<td>> 12</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Musicien</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Date et heure de concert</td>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Concert</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Lieu de concert</td>
|
||||||
|
<td>Alphabétique</td>
|
||||||
|
<td>50</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Concert</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Tarif</td>
|
||||||
|
<td>Numérique</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>Concert</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Date et heure de répétition</td>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Répétition</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Lieu de répétition</td>
|
||||||
|
<td>Alphabétique</td>
|
||||||
|
<td>50</td>
|
||||||
|
<td>Obligatoire</td>
|
||||||
|
<td>Répétition</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<td class="text-left">
|
|
||||||
<strong>{props.isTechnical ? "Table" : "Document"}</strong>
|
|
||||||
</td>
|
|
||||||
<td colSpan={3} class="text-left">
|
|
||||||
{props.isTechnical ? table.tableName : table.documentName}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{props.isTechnical && (
|
|
||||||
<tr>
|
|
||||||
{table.primaryKeys && table.primaryKeys.length > 0 && (
|
|
||||||
<>
|
|
||||||
<td class="text-left">
|
|
||||||
<strong>Clé primaire</strong>
|
|
||||||
</td>
|
|
||||||
<td class="text-left">({table.primaryKeys.join(", ")})</td>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{table.foreignKeys && table.foreignKeys.length > 0 && (
|
|
||||||
<>
|
|
||||||
<td class="text-left">
|
|
||||||
<strong>Clé(s) étrangère(s)</strong>
|
|
||||||
</td>
|
|
||||||
<td class="text-left">{table.foreignKeys.join(", ")}</td>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
</table>
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ Le MLD est la suite normale et directe du MCD dans le processus Merise. Son but
|
|||||||
|
|
||||||
On parlera plus tard du MRD, mais globalement : c'est la même chose que le MLD !
|
On parlera plus tard du MRD, mais globalement : c'est la même chose que le MLD !
|
||||||
|
|
||||||
## 🤔 Qu'est-ce que le MLD ?
|
## Qu'est-ce que le MLD ?
|
||||||
|
|
||||||
Le **MLD** est un schéma qui va nous permettre de représenter les données que l'on a récupérées dans le MCD, mais en ajoutant des détails techniques.
|
Le **MLD** est un schéma qui va nous permettre de représenter les données que l'on a récupérées dans le MCD, mais en ajoutant des détails techniques.
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ Il va nous permettre de représenter les différentes données que l'on a, regro
|
|||||||
|
|
||||||
Contrairement au MCD, le MLD n'est pas destiné à être compris par le client.
|
Contrairement au MCD, le MLD n'est pas destiné à être compris par le client.
|
||||||
|
|
||||||
## 🔍 Exemple de MLD
|
## Exemple de MLD
|
||||||
|
|
||||||
Reprenons le premier exemple de MCD, dans l'article précédent :
|
Reprenons le premier exemple de MCD, dans l'article précédent :
|
||||||
|
|
||||||
|
|||||||
@ -4,139 +4,4 @@ description: Apprenez à créer le MPD dans Merise, la dernière étape pour con
|
|||||||
tags: [Backend, Merise, BDD, MCD, MLD, MPD, SQL]
|
tags: [Backend, Merise, BDD, MCD, MLD, MPD, SQL]
|
||||||
---
|
---
|
||||||
|
|
||||||
import DictionnaryTable from "../dictionnaire-de-donnees/DictionnaryTable";
|
En cours de rédaction...
|
||||||
import Callout from "@/components/Callout";
|
|
||||||
import tabs from "./tabs";
|
|
||||||
|
|
||||||
Prêt·e pour la dernière étape de la méthodologie Merise ? 🎉
|
|
||||||
Alors sans plus tarder, accueillons comme il se doit le **MPD** _(Modèle Physique de Données)_ !
|
|
||||||
|
|
||||||
## 🤔 Qu'est-ce que le MPD ?
|
|
||||||
|
|
||||||
Le **MPD** est la dernière étape de la méthodologie Merise.
|
|
||||||
Il reprend les éléments du MLD en ajoutant les derniers **détails techniques** nécessaires
|
|
||||||
pour implémenter le modèle dans un **SGBD** _(Système de Gestion de Base de Données)_.
|
|
||||||
|
|
||||||
**Ces détails techniques sont** :
|
|
||||||
|
|
||||||
- Le type de données de chaque colonne _(ex: `VARCHAR`, `INT`, `DATE`, etc.)_
|
|
||||||
- La taille de chaque colonne _(ex: `VARCHAR(255)`, `INT(11)`, etc.)_
|
|
||||||
- Les contraintes d'intégrité _(ex: `NOT NULL`, `UNIQUE`, etc.)_
|
|
||||||
- Les clés étrangères _(ex: `FOREIGN KEY`, `REFERENCES`, etc.)_
|
|
||||||
|
|
||||||
## 🔍 Exemple de MPD
|
|
||||||
|
|
||||||
À partir du **MLD** _(et **MRD** si existant)_ et du **dictionnaire de données**, on va pouvoir créer le MPD.
|
|
||||||
|
|
||||||
Faisons la transition de l'exemple de MLD basique que l'on a vu précédemment :
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
En prenant en considération que l'application va être développée avec **PostgreSQL**, on prendra soin d'utiliser
|
|
||||||
les **types de données** et les **contraintes d'intégrité** qui lui sont propres.
|
|
||||||
|
|
||||||
Voici à quoi il ressemble :
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Avec ce schéma, il est facile d'identifier les différentes tables, leurs colonnes, les types de données,
|
|
||||||
les contraintes d'intégrité, ainsi que les clés primaires et étrangères qui relient les tables entre elles.
|
|
||||||
|
|
||||||
Une fois le MPD créé, il est possible de le traduire en **SQL** pour créer les tables dans le SGBD.
|
|
||||||
Voici un exemple de code SQL pour créer les tables correspondantes au MPD ci-dessus :
|
|
||||||
|
|
||||||
<tabs.sqlExample />
|
|
||||||
|
|
||||||
## 📊 Dictionnaire de données
|
|
||||||
|
|
||||||
Tu te souviens du **dictionnaire de données** que l'on a créé lors du brief avec le client ? Juste avant de passer au MCD ?
|
|
||||||
Il est maintenant possible de le mettre jour avec les informations du SGBD utilisé !
|
|
||||||
|
|
||||||
Bien entendu ce n'est pas obligatoire, mais c'est une bonne source d'informations pour
|
|
||||||
les développeurs et les administrateurs de la base de données 😉
|
|
||||||
|
|
||||||
Pour rappel, voici le dictionnaire de données **non technique** que nous avions fait :
|
|
||||||
|
|
||||||
<DictionnaryTable />
|
|
||||||
|
|
||||||
En ajoutant les informations techniques, il devient :
|
|
||||||
|
|
||||||
<DictionnaryTable isTechnical />
|
|
||||||
|
|
||||||
Ça en fait du beau monde ! 😅
|
|
||||||
|
|
||||||
Il est important de noter que le dictionnaire de données doit être mis à jour à chaque fois qu'une modification
|
|
||||||
est apportée au modèle de données ainsi qu'à la base de données.
|
|
||||||
|
|
||||||
Maintenant, il est temps de réaliser le **MPD** à partir du **MLD** et du **dictionnaire de données** !
|
|
||||||
|
|
||||||
## 🛠️ Outils pour créer le MPD
|
|
||||||
|
|
||||||
Bien que j'ai recommandé d'utiliser [Looping](https://looping.fr/) pour créer les schémas de données,
|
|
||||||
il ne permet pas de créer le MPD.
|
|
||||||
|
|
||||||
Il n'est pas pour autant à mettre à la poubelle, car il permet de créer le MCD et le MLD très facilement, ainsi que
|
|
||||||
le LDD _(Langage de Définition de Données)_ dont on va parler un peu plus tard !
|
|
||||||
|
|
||||||
Divers outils en ligne permettent de générer des schémas graphiques de bases de données.
|
|
||||||
Cependant, ils ne sont pas tous adaptés à la création de MPD.
|
|
||||||
|
|
||||||
La plupart du temps, on retrouvera des outils qui permettent de réaliser des ERD _(Entity Relationship Diagram)_.
|
|
||||||
La différence dans ces outils est qu'ils se basent davantage sur une syntaxe de type **UML** _(Unified Modeling Language)_.
|
|
||||||
|
|
||||||
<Callout type="question" title="Comment reconnaître si mon outil utilise une syntaxe de type UML ?">
|
|
||||||
En général, les outils qui utilisent une syntaxe de type UML utilisent des **losanges** pour représenter les relations entre les entités.
|
|
||||||
Dans le cas de Merise, on utilise des **lignes** et **flèches basiques** pour représenter les relations entre les entités/tables.
|
|
||||||
|
|
||||||
Il est aussi possible que tu tombes sur des "pattes de poulet" _(comme dirait une consœur jurée)_ ou **crow's foot notation**
|
|
||||||
qui est une autre façon de représenter les relations entre les entités/tables.
|
|
||||||
|
|
||||||
C'est joli, **mais c'est pas Merise** ! 😅
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
De mon côté, j'utilise [DrawDB](https://drawdb.app/) qui est un outil en ligne gratuit et open-source.
|
|
||||||
Il permet de créer des schémas de bases de données avec la possibilité de configurer l'apparence des lignes de relation,
|
|
||||||
ainsi que de générer un diagramme à partir d'un fichier SQL.
|
|
||||||
|
|
||||||
## 🔨 Création du MPD
|
|
||||||
|
|
||||||
Pour créer le MPD, il va juste falloir t'armer de patience selon la taille de ton MLD et de ton outil.
|
|
||||||
|
|
||||||
Dans ton outil, tu devras indiquer les types de données et les contraintes d'intégrité pour chaque colonne de chaque table.
|
|
||||||
Mais ça tombe bien, on a déjà fait le plus gros du travail avec le MLD et le dictionnaire de données !
|
|
||||||
|
|
||||||
À la fin, on se retrouve avec un schéma qui ressemble à ça :
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 📜 Préparation du LDD
|
|
||||||
|
|
||||||
Dernière ligne droite : le **LDD** _(Langage de Définition de Données)_ !
|
|
||||||
|
|
||||||
Le **LDD** correspond tout simplement à la création des tables dans le SGBD, par l'utilisation des commandes SQL
|
|
||||||
comme `CREATE TABLE`, `ALTER TABLE`, `DROP TABLE`, etc.
|
|
||||||
|
|
||||||
Il est possible de le créer à partir de [DrawDB](https://drawdb.app/) en exportant le schéma au format SQL, mais également
|
|
||||||
depuis [Looping](https://looping.fr/) !
|
|
||||||
|
|
||||||
De notre côté, voici à quoi ressemble le LDD pour le MPD ci-dessus :
|
|
||||||
|
|
||||||
<tabs.sqlBandManager />
|
|
||||||
|
|
||||||
Et voilà, on en a fini avec le MPD ! 🎉
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Ça y est, on peut souffler un bon coup ! 🍹☀️
|
|
||||||
|
|
||||||
Non seulement on a créé le **MPD**, mais on a également mis à jour le **dictionnaire de données** avec les informations techniques
|
|
||||||
tout en préparant le **LDD** pour créer les tables dans le SGBD.
|
|
||||||
On peut le dire : on est des pros de la méthodologie Merise ! 😎
|
|
||||||
|
|
||||||
... ou presque ! Merise va plus loin que la simple modélisation de bases de données.
|
|
||||||
Mais ça, je t'invite à le découvrir par toi-même 😉
|
|
||||||
|
|
||||||
Si tu souhaites aller plus loin dans la méthodologie Merise, je te recommande de lire la
|
|
||||||
[quatrième édition du guide pratique Merise](https://www.editions-eni.fr/livre/merise-guide-pratique-4e-edition-modelisation-des-donnees-et-des-traitements-manipulations-avec-le-langage-sql-conception-d-une-application-mobile-android-ou-ios-9782409046667)
|
|
||||||
aux Éditions ENI.
|
|
||||||
Il a été écrit par [Jean-Luc Baptiste](https://www.editions-eni.fr/jean-luc-baptiste) qui maîtrise le sujet sur le bout des doigts.
|
|
||||||
|
|||||||
@ -1,125 +0,0 @@
|
|||||||
import { Snippet } from "@/components/Snippet";
|
|
||||||
|
|
||||||
const sqlExampleSnippets = [
|
|
||||||
{
|
|
||||||
name: "Exemple de LDD",
|
|
||||||
codeLanguage: "sql",
|
|
||||||
withLineNumbers: true,
|
|
||||||
code: `CREATE TABLE "table_1" (
|
|
||||||
"id_table_1" INTEGER NOT NULL UNIQUE,
|
|
||||||
"column_2" VARCHAR(50) NOT NULL,
|
|
||||||
"column_3" VARCHAR(50) NOT NULL,
|
|
||||||
"table_3_id" INTEGER NOT NULL,
|
|
||||||
PRIMARY KEY("id_table_1")
|
|
||||||
);
|
|
||||||
CREATE INDEX "table_1_index_0"
|
|
||||||
ON "table_1" ("id_table_3");
|
|
||||||
|
|
||||||
CREATE TABLE "table_3" (
|
|
||||||
"id_table_3" INTEGER NOT NULL UNIQUE GENERATED BY DEFAULT AS IDENTITY,
|
|
||||||
"column_2" VARCHAR(50) NOT NULL,
|
|
||||||
"column_3" VARCHAR(50) NOT NULL,
|
|
||||||
"table_3_id" INTEGER,
|
|
||||||
PRIMARY KEY("id_table_3")
|
|
||||||
);
|
|
||||||
CREATE INDEX "table_3_index_0"
|
|
||||||
ON "table_3" ("id_table_3");
|
|
||||||
|
|
||||||
CREATE TABLE "table_2" (
|
|
||||||
"id_table_2" INTEGER NOT NULL UNIQUE GENERATED BY DEFAULT AS IDENTITY,
|
|
||||||
"column_2" VARCHAR(50) NOT NULL,
|
|
||||||
"column_3" VARCHAR(50) NOT NULL,
|
|
||||||
PRIMARY KEY("id_table_2")
|
|
||||||
);
|
|
||||||
CREATE INDEX "table_2_index_0"
|
|
||||||
ON "table_2" ("id_table_2");
|
|
||||||
|
|
||||||
CREATE TABLE "table_1_contains_table_2" (
|
|
||||||
"table_1_id" INTEGER NOT NULL,
|
|
||||||
"table_2_id" INTEGER NOT NULL,
|
|
||||||
PRIMARY KEY("table_1_id", "table_2_id")
|
|
||||||
);
|
|
||||||
CREATE UNIQUE INDEX "table_1_contains_table_2_index_0"
|
|
||||||
ON "table_1_contains_table_2" ("table_1_id", "table_2_id");
|
|
||||||
|
|
||||||
ALTER TABLE "table_1"
|
|
||||||
ADD FOREIGN KEY("table_3_id") REFERENCES "table_3"("id_table_3")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "table_3"
|
|
||||||
ADD FOREIGN KEY("id_table_3") REFERENCES "table_3"("table_3_id")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "table_1"
|
|
||||||
ADD FOREIGN KEY("id_table_1") REFERENCES "table_1_contains_table_2"("table_1_id")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "table_1_contains_table_2"
|
|
||||||
ADD FOREIGN KEY("table_2_id") REFERENCES "table_2"("id_table_2")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const sqlBandManagerSnippets = [
|
|
||||||
{
|
|
||||||
name: "LDD final",
|
|
||||||
codeLanguage: "sql",
|
|
||||||
withLineNumbers: true,
|
|
||||||
code: `CREATE TABLE "musician" (
|
|
||||||
"id_musician" SERIAL NOT NULL,
|
|
||||||
"lastname" VARCHAR(30) NOT NULL,
|
|
||||||
"firstname" VARCHAR(30) NOT NULL,
|
|
||||||
"instruments" VARCHAR[] NOT NULL,
|
|
||||||
"email" VARCHAR(50) NOT NULL,
|
|
||||||
"password" CHAR(64) NOT NULL,
|
|
||||||
PRIMARY KEY("id_musician")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "event" (
|
|
||||||
"id_event" SERIAL NOT NULL,
|
|
||||||
"datetime" TIMESTAMP NOT NULL,
|
|
||||||
"location" VARCHAR(30) NOT NULL,
|
|
||||||
PRIMARY KEY("id_event")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "concert" (
|
|
||||||
"id_concert" SERIAL NOT NULL,
|
|
||||||
"price" MONEY,
|
|
||||||
"event_id" SERIAL NOT NULL,
|
|
||||||
PRIMARY KEY("id_concert")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "rehearsal" (
|
|
||||||
"id_rehearsal" SERIAL NOT NULL,
|
|
||||||
"event_id" SERIAL NOT NULL,
|
|
||||||
PRIMARY KEY("id_rehearsal")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "musician_participates_event" (
|
|
||||||
"musician_id" SERIAL NOT NULL,
|
|
||||||
"event_id" SERIAL NOT NULL,
|
|
||||||
PRIMARY KEY("musician_id", "event_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE "concert"
|
|
||||||
ADD FOREIGN KEY("event_id") REFERENCES "event"("id_event")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "rehearsal"
|
|
||||||
ADD FOREIGN KEY("event_id") REFERENCES "event"("id_event")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "musician"
|
|
||||||
ADD FOREIGN KEY("id_musician") REFERENCES "musician_participates_event"("musician_id")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
|
||||||
|
|
||||||
ALTER TABLE "event"
|
|
||||||
ADD FOREIGN KEY("id_event") REFERENCES "musician_participates_event"("event_id")
|
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION;`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
|
||||||
sqlExample: () => <Snippet snippets={sqlExampleSnippets} />,
|
|
||||||
sqlBandManager: () => <Snippet snippets={sqlBandManagerSnippets} />,
|
|
||||||
};
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
Loading…
Reference in New Issue
Block a user