%reload_ext mocodo
from IPython import display
from pathlib import Path
import os
if Path.cwd().name != "mocodo_notebook":
Path("mocodo_notebook").mkdir(parents=True, exist_ok=True)
os.chdir("mocodo_notebook")
Mocodo est un logiciel d'aide à l'enseignement et à l'apprentissage des bases de données relationnelles.
Vous pouvez utiliser Mocodo :
Ci-dessous, un exemple d'utilisation sous Jupyter Notebook. L'appel du programme est en première ligne ; le texte-source proprement dit, lignes suivantes. En sortie, le diagramme conceptuel, égayé au passage par l'option --colors
:
%%mocodo --colors ocean
Client: Réf. client [VARCHAR(8)], Nom [VARCHAR(255)], Prénom [VARCHAR(255)], Adresse [VARCHAR(255)]
Passer, 0N Client, 11 Commande
Commande: Num. commande [VARCHAR(8)], Date [DATE], Montant [DECIMAL(10,2)]
Inclure, 1N Commande, 0N Produit: Quantité [INTEGER]
Produit: Réf. produit [VARCHAR(8)], Libellé [VARCHAR(50)], Prix unitaire [DECIMAL(10,2)]
L'appel précédent a automatiquement enregistré le texte-source sous le nom de sandbox.mcd
. Renommons-le ccp.mcd
pour y avoir accès tout au long de ce document.
Path("sandbox.mcd").rename("ccp.mcd");
On peut le récupérer avec --input
pour lui appliquer diverses opérations. Ainsi, l'appel suivant génère et affiche son MLD, son diagramme relationnel et son DDL :
%mocodo --input ccp --transform mld diagram ddl --colors mondrian
Dans la suite, pour épargner la frappe, les options --input
et --transform
seront respectivement abrégées en -i
et -t
.
Les opérations de conversion ne se limitent pas forcément au schéma relationnel. En voici une qui extrait un dictionnaire des données, par défaut sous la forme d'un tableau Markdown à trois colonnes :
%mocodo -i ccp -t data_dict
Une autre qui transcrit le MCD dans la notation crow's foot (crow
) pour Mermaid (mmd
) :
%mocodo -i ccp -t crow:mmd
Le rendu des diagrammes décrits dans des langages-tiers (comme Mermaid) n'est pas directement pris en charge, mais peut être délégué (--defer
) de façon transparente au service web approprié. Dans ce cas, c'est la sortie graphique qui est affichée :
%mocodo -i ccp -t crow:mmd --defer
Une réécriture transforme un MCD Mocodo en un autre MCD Mocodo (au contraire d'une conversion, qui produit un animal d'une espèce différente).
Heureusement, l'utilisateur n'a pas à réfléchir si la transformation qu'il souhaite appliquer est une réécriture ou une conversion : dans les deux cas, il invoque -t
(c'est-à-dire --transform
), et Mocodo se débrouille.
En guise de premier exemple de réécriture, mettons les noms des entités et associations (boxes
) en majuscules, et les libellés (labels
) en ASCII et snake case :
%mocodo -i ccp -t upper:boxes ascii:labels snake:labels --colors brewer+3
Remarquez que l'exécution d'une réécriture affiche, au-dessous du diagramme, le code-source résultant. Celui-ci est précédé de la commande magique originale, privée de l'option -i
et de toute opération de réécriture. Ces dispositions permettent de continuer à travailler directement dessus si on le copie-colle dans une autre cellule.
Plusieurs opérations de réécriture de nature sémantique sont également offertes. Par exemple, on peut décomposer un MCD quelconque en un MCD équivalent, mais n'employant que des dépendances fonctionnelles et des entités faibles :
%mocodo -i ccp -t explode:weak,arity=2 arrange:wide --seed=3 --colors brewer+3
Notez l'argument arrange:wide
. Il a procédé à une réorganisation aléatoire des boîtes, ce que l'insertion de deux nouvelles associations de dépendance fonctionnelles avait rendu nécessaire. Quant à l'option --seed=3
, elle garantit que le résultat sera le même à chaque exécution.
Après cet aperçu de quelques-unes des fonctionnalités de Mocodo, entrons dans les détails.
Comme nous l'avons dit, vous pouvez utiliser Mocodo sans rien installer. Il vous suffit d'aller sur mocodo.net et de commencer à taper votre MCD. Appuyez à tout moment sur le ventilateur pour rafraîchir les diagrammes conceptuel et relationnel. Quand le résultat vous convient, appuyez sur le bouton de téléchargement pour récupérer une archive ZIP contenant tous les fichiers d'entrée et de sortie spécifiés.
Mocodo online est conçu pour une utilisation occasionnelle et/ou interactive, et son interface vise avant tout à la simplicité. Vous n'avez donc accès qu'aux options essentielles du programme. Si vous en voulez davantage, tant en termes de paramétrage que de calcul ou de fonctionnalités, nous vous conseillons d'installer Mocodo sur votre machine.
Mocodo est un programme écrit en Python 3. Si vous êtes sous macOS ou Linux, il est déjà installé. Dans le cas contraire, vous devrez peut-être le faire.
Une fois Python présent sur votre machine, tapez sous un terminal:
python -m pip install mocodo
Puis testez-le :
mocodo
Invoqué sous cette forme, Mocodo récupère le texte d'entrée du MCD dans le répertoire courant sous le nom de sandbox.mcd
. Si ce fichier n'existe pas, il y sera automatiquement créé avec un MCD d'exemple. Par la suite, vous n'aurez qu'à le garder ouvert sous un éditeur de texte, afin de le modifier à votre fantaisie avant de relancer la commande.
Si votre système se plaint que cette commande n'existe pas, localisez le fichier mocodo
et ajoutez à votre PATH
le chemin du répertoire contenant:
La ligne donnée précédemment installe en fait, en plus de Mocodo, sa « commande magique » pour Jupyter Notebook. Nous l'avons déjà invoquée plusieurs fois dans ce document :
python -m pip install mocodo
Mocodo fonctionne parfaitement sans autres dépendances que la bibliothèque requests
. Cependant, si vous souhaitez générer des figures en PDF ou en PNG :
python -m pip install cairosvg
Si vous souhaitez pouvoir copier directement le résultat d'une réécriture dans le presse-papier :
python -m pip pyperclip
Pour mettre la « commande magique » mocodo
à disposition d'un notebook donné, évaluez dans celui-ci la cellule suivante:
%reload_ext mocodo
Techniquement, %load_ext mocodo
suffit, mais cette forme vous épargnera un message d'erreur si vous réévaluez ultérieurement la cellule.
Pour tester la commande :
%%mocodo
MISSION: accomplie
Pour charger automatiquement mocodo
à chaque ouverture d'un notebook (ce qui dispense d'évaluer %load_ext mocodo
) :
exécutez sous un terminal :
ipython profile create
éditez le fichier créé (p. ex.: ~/.ipython/profile_default/ipython_config.py
) en remplaçant la ligne suivante :
# c.TerminalIPythonApp.extensions = []
par celle-ci :
c.InteractiveShellApp.extensions = ["mocodo"]
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, 0N CLIENT, 11 COMMANDE
COMMANDE: Num. commande, Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Passons en revue les principes de la syntaxe. Ils ne devraient pas poser trop de problèmes.
La première ligne ne fait pas partie de la définition du MCD. Sous Jupyter Notebook, elle dénote l'appel à une « commande magique », qui lance Mocodo sur le reste de la cellule. En dehors d'un notebook, vous n'en avez pas besoin, et toute ligne commençant par un pourcentage (%
) sera considérée comme un commentaire.
Une entité est définie par :
$$ \overbrace{\texttt{COMMANDE}}^{\text{son nom}} \quad \overbrace{\texttt{:}}^{\text{deux-points}} \quad \overbrace{\texttt{Num. commande, Date, Montant}}^{\text{ses attributs séparés par des virgules}} $$Notez que le premier attribut d'une entité est considéré par défaut comme son identifiant, et donc souligné.
Une association est définie par :
$$ \overbrace{\texttt{INCLURE}}^{\text{son nom}} \quad \overbrace{\texttt{,}}^{\text{une virgule}} \quad \overbrace{ \underbrace{\texttt{1N}}_{\text{cardinalités}} \underbrace{\texttt{COMMANDE}}_{\text{entité}} \quad , \quad \underbrace{\texttt{0N}}_{\text{cardinalités}} \underbrace{\texttt{PRODUIT}}_{\text{entité}} }^{\text{ses pattes séparées par des virgules}} \quad \overbrace{\texttt{:}}^{\text{deux-points}} \quad \overbrace{\texttt{Quantité}}^{\text{ses attributs séparés par des virgules}} $$Notez que pour les associations sans attributs (comme PASSER), le deux-points est facultatif.
Astuce. Si vous recopiez un MCD ou que vous l'avez bien en tête, commencez par les associations et, à tout moment, faites apparaître les entités manquantes (double clic sur le lapin magique sous Mocodo online). Elles auront comme identifiant le nom de l'entité en minuscules, par défaut précédé de « id. » (sauf pour les entités DATE et PÉRIODE). Vous n'aurez plus qu'à remplir les autres attributs :
%%mocodo -t guess:entities
Réserver, 1N Client, 1N Chambre, 0N Date: Durée
Lorsque l'une des cardinalités maximales d'une association binaire est 1 (ou quelquefois 0), on désigne cette association sous le nom de dépendance fonctionnelle. On la figure souvent par un cercle portant le symbole DF : cela évite de se creuser la tête pour trouver un nom à une association qui (spoiler) disparaîtra corps et biens au moment du passage au relationnel.
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
DF, 0N CLIENT, 11 COMMANDE
COMMANDE: Num. commande, Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Quelquefois appelées circulaires, unaires ou récursives, elles associent une entité à elle-même. Voici par exemple une représentation des filiations patrilinéaires (le 01 permet d'« arrêter » la remontée des ancêtres) :
%%mocodo
HOMME: Num. SS, Nom, Prénom
ENGENDRER, 0N HOMME, 01 HOMME
Préfixez d'un tiret bas (_
) les second, troisième, etc. attributs pour les inclure dans l'identifiant.
%%mocodo
GRATTE-CIEL: latitude, _longitude, nom, hauteur, année de construction
Suffixez d'un chevron (<
ou >
) les cardinalités de la patte concernée. La direction indiquée se lit en partant de l'association et en allant vers l'entité.
%%mocodo
Peut recevoir, 1N> Groupe sanguin, 1N< Groupe sanguin
Groupe sanguin: type de sang
Appartient, 11> Personne, 0N Groupe sanguin
Personne: Num. SS, Nom, Prénom, Sexe
Engendre, 0N< Personne, 22> Personne
Comme on l'a vu dans l'introduction, chaque attribut peut être assorti d'un type entre crochets, qui servira lors de la conversion en SQL. À partir de la version 4.0, Mocodo est capable de deviner le type des attributs usuels :
%%mocodo -t guess:types --select source
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, 0N CLIENT, 11 COMMANDE
COMMANDE: Num. commande, Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Mocodo combine les avantages de l'approche diagram as code (comme PlantUML, Mermaid ou Graphviz), avec la liberté de positionnement offerte par les logiciels WYSIWYG (what you see is what you get).
Sa grande originalité est de se baser sur l'ordre et la séparation des lignes de la description pour définir une mise en page qui se révèle suffisante dans la majorité des cas.
Premier principe : les boîtes (entités et associations) définies sur des lignes consécutives sont tracées sur une seule rangée.
Si l'on écrit les définitions sur des lignes consécutives, on se retrouve donc vite avec des chevauchements qui ne sautent pas forcément aux yeux :
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
COMMANDE: Num. commande, Date, Montant
PRODUIT: Réf. produit, Libellé, Prix unitaire
PASSER, 0N CLIENT, 11 COMMANDE
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
L'option --detect_overlaps
(active par défaut sous Mocodo online) signale le problème et donne la solution :
%mocodo -i sandbox --detect_overlaps
Limitation. Seuls les chevauchements mettant en jeu des pattes horizontales ou verticales sont détectés.
Deuxième principe : pour commencer une nouvelle rangée, il faut sauter une ligne :
%%mocodo
SCELERISQUE LOREM: blandit, elit, ligula
EROS, 11 SCELERISQUE LOREM, 1N PELLENTESQUE IPSUM: metus, congue
NIBH, 1N SCELERISQUE LOREM, 11 PELLENTESQUE IPSUM
PELLENTESQUE IPSUM: tincidunt, bibendum, consequat, integer
Les centres des boîtes sont placés aux intersections d'une grille invisible. Ils sont donc alignés aussi bien horizontalement que verticalement. De plus, dans un but esthétique, le dessin fait l'objet d'une compression dans les deux dimensions. Par exemple, ci-dessus, un espace horizontal négatif a été créé entre le bord droit de l'entité de gauche et le bord gauche de l'entité de droite.
Mocodo permet de calculer facilement les symétriques d'un MCD :
-t flip:v
;-t flip:h
;-t flip:d
.-t flip:vhd
.%mocodo -i sandbox --select mcd -t flip:h
Corrections de la version 4.0.
Astuce. Transposez le MCD temporairement pour réaliser plus facilement certaines opérations d'édition en colonne, en particulier sous Mocodo online.
Mocodo centre les rangées qui contiennent moins de boîtes que les autres. Ce comportement n'est pas toujours idéal :
%%mocodo
Ultrices, 01 Aliquet, 0N Aliquet
Aliquet: hendrerit, metus, lacus, quis
Risus, 1N Aliquet, 0N Massa
Massa: metus, posuere
Euismod, 0N Massa, 0N Massa
Convallis, 0N Aliquet, 0N Ante: vestibulum
Tincidunt, 11 Ante, 0N Massa
Gravida: ornare
Rutrum, 0N Gravida, 0N Ante, 0N Aliquet: faucibus, curae
Ante: vitae, tempor
L'utilisateur peut alors spécifier les espacements qu'il désire en complétant les rangées par des boîtes invisibles dont le seul rôle est de « pousser » les autres à l'emplacement voulu. Cela se fait en insérant manuellement des lignes réduites au caractère deux-points :
%%mocodo
Ultrices, 01 Aliquet, 0N Aliquet
Aliquet: hendrerit, metus, lacus, quis
Risus, 1N Aliquet, 0N Massa
Massa: metus, posuere
Euismod, 0N Massa, 0N Massa
:
:
Convallis, 0N Aliquet, 0N Ante: vestibulum
Tincidunt, 11 Ante, 0N Massa
Gravida: ornare
Rutrum, 0N Gravida, 0N Ante, 0N Aliquet: faucibus, curae
:
Ante: vitae, tempor
Cependant, en général, ces manipulations sont inutiles : Mocodo est capable de calculer tout seul des plongements à la fois compacts et esthétiques. Voici une compilation des réarrangements automatiques du MCD précédent produits par :
%mocodo -i sandbox -t arrange --seed 1
%mocodo -i sandbox -t arrange --seed 2
%mocodo -i sandbox -t arrange --seed 3
%mocodo -i sandbox -t arrange --seed 4
%mocodo -i ../examples/four_random_layouts --scale 0.8
Préfixez d'un tiret bas (_
) une cardinalité 11 pour indiquer que l'entité distinguée est faible.
%%mocodo
ŒUVRE: Cote œuvre, Titre, Date parution
DF, 1N ŒUVRE, _11 EXEMPLAIRE
EXEMPLAIRE: Num. exemplaire, État du livre, Date d'achat
Dans le diagramme, les identifiants (ou plutôt, discriminateurs) d'une telle entité seront soulignés en pointillés, tandis que le 11 sera par défaut souligné d'un trait plein.
Notez qu'un discriminateur n'est pas toujours obligatoire :
%%mocodo
Employé: Num. employé, Nom employé, Prénom employé
Df, _11 Conjoint, 01 Employé
Conjoint: _Nom conjoint, Prénom conjoint
Son absence implique cependant que l'occurrence de l'entité forte qui « renforce » une occurrence de l'entité faible ne peut en renforcer une autre : d'où la cardinalité maximale 1 sur la patte distinguant EMPLOYÉ.
Mocodo rejettera donc la version « polygame » du MCD précédent (avec 0N à la place de 01) :
%%mocodo
Employé: Num. employé, Nom employé, Prénom employé
Df, _11 Conjoint, 0N Employé
Conjoint: _Nom conjoint, Prénom conjoint
L'héritage permet de regrouper dans une entité, dite « mère », les attributs communs à plusieurs autres entités, dites « filles », qui se distinguent les unes des autres par des attributs spécifiques.
Pour définir une spécialisation, insérez une ligne spécifiant :
$$ \overbrace{\texttt{/}\,\texttt{XT}\,\texttt{\\}}^{\text{sa nature entre barres obliques}} \qquad \overbrace{\texttt{<}\,\texttt{-}}^{\text{son type de flèche}} \qquad \overbrace{\texttt{mère}}^{\text{une entité}} \qquad \overbrace{\texttt{,}}^{\text{une virgule}} \qquad \overbrace{\texttt{fille 1, fille 2, fille 3}}^{\text{des entités séparées par des virgules}} \qquad \overbrace{\texttt{: discriminateur}}^{\text{optionnellement, un attribut}} $$%%mocodo
Personne: num SS, nom, prénom
/XT\ Personne <- Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Inscrivez dans le triangle les symboles de votre choix pour prendre une part active aux guerres culturelles de notre temps :
Totalité | Exclusion | Symboles | Exemple de population | Toute personne est : |
---|---|---|---|---|
oui | oui | /XT\ |
♂♂♂♂♂♂♂ ♀♀♀♀♀♀♀♀♀♀ |
- soit un homme - soit une femme |
non | oui | /X\ |
♂♂♂♂♂♂♂♂ ♀♀♀♀♀♀ ○○○○ |
- soit un homme - soit une femme - soit aucun des deux |
oui | non | /T\ |
♂♂♂♂♂♂ ♀♀♀♀♀♀♀♀ ⚥⚥⚥⚥ |
- soit un homme - soit une femme - soit les deux à la fois |
non | non | /\ |
♂♂♂♂♂ ♀♀♀♀♀♀ ○○○○ ⚥⚥⚥⚥ |
- soit un homme - soit une femme - soit aucun des deux - soit les deux à la fois |
Pour définir une telle contrainte, ajoutez n'importe où une ligne spécifiant :
$$ \overbrace{\texttt{(}\,\texttt{FOO}\,\texttt{)}}^{\text{son nom entre parenthèses}} \quad \overbrace{ \texttt{-}\,\texttt{>} \texttt{boîte 1,} \quad \texttt{.}\,\texttt{.} \texttt{boîte 2,} \quad \texttt{-}\,\texttt{-} \texttt{boîte 3,} \quad \texttt{boîte 4} }^{\text{les types de liens et les boîtes qu'elle met en jeu, séparés par des virgules}} \quad \overbrace{\texttt{:}\,\,\texttt{horizontale, verticale}}^{\text{optionnellement, ses coordonnées}} $$Précisions.
-
(trait plein) ou .
(trait pointillé), optionnellement précédés d'un symbole <
(flèche vers la contrainte) et/ou suivis d'un symbole >
(flèche vers la boîte).:
pour leur faire de la place.Voici un exemple concret, adapté de la Fig. 7.37 de Merise, deuxième génération (Dominique Nanci et Bernard Espinasse, 4e éd., 2001) :
%%mocodo -t
:::
Dépôt: num dépôt, surface
:
Louer, 11 Commande, 0N Dépôt
:
Stocker, 1N Dépôt, 1N Article: quantité
Commande: num. commande, date
Composer, 1N Commande, 0N Article
:
Article: réf. article, prix
(I) ->Stocker, ..Dépôt, ..Article, --Composer, --Louer, Commande
Notez que pour Mocodo, ces contraintes sont purement décoratives : le passage au niveau relationnel ou physique n'en tient pas compte.
Dans le MCD ci-dessous, le petit rond et l'enveloppe pointillée indiquent qu'une réservation d'une chambre donnée à une date donnée ne peut être faite que par un seul client :
%%mocodo --colors ocean # changement de palette pour faire apparaître un fond semi-transparent
Date: Date
Réserver, /1N Client, 1N Chambre, 0N Date: Durée
Chambre: Num. chambre, Prix
Client: Id. client
La syntaxe est minimale : une simple barre oblique /
avant la cardinalité de l'entité-cible.
S'il y a au maximum deux entités à agréger, et que l'angle formé par l'association et les entités est plat ou rectangle, une enveloppe de points matérialise la pseudo-entité.
Sinon, pour des raisons de simplicité du code et de clarté du diagramme, l'enveloppe n'est pas affichée. Cependant, le petit rond subsiste et le reste des traitements est bien sûr inchangé.
Remarques.
La notion d'agrégation n'a pas très bonne presse dans les milieux autorisés. Ceux-ci lui préfèrent généralement celle (équivalente) de contrainte d'intégrité fonctionnelle à unicité complète. Pour rentrer dans leurs bonnes grâces (et désactiver du même coup la visualisation de l'enveloppe et du petit rond), il suffit d'expliciter la contrainte correspondante dans le MCD précédent. Mocodo peut le faire pour vous :
%mocodo -i sandbox -t create:cifs arrange --seed=12 --colors ocean
Remarquez que la visibilité de la CIF est assurée par le positionnement de celle-ci sur une boîte invisible introduite à cet effet : si vous rectifiez ce positionnement, vous pouvez bien sûr supprimer cette boîte.
Vous avez également le droit d'alléger la visualisation des CIFs complètes en transformant les traits pleins "--"
des entités émettrices en traits invisibles ""
. Là encore, Mocodo peut le faire pour vous :
%mocodo -i sandbox -t create:cifs=light arrange --seed=12 --colors ocean
Limitation. Au niveau fonctionnel, c'est toujours la barre oblique qui conditionne le traitement des CIF. Par conséquent, les CIF à unicité incomplète ne sont prises en charge qu'au niveau visuel.
Mocodo 4.1.1 relaxe par défaut (sauf dans la version en ligne) la contrainte de Merise restreignant aux entités la présence d'identifiants. Si vous l'osez, vous pouvez donc obtenir le même schéma relationnel avec le MCD « allégé » suivant :
%%mocodo -t
Client: Id. client
Réserver, 1N Client, 0N Chambre: _Date, Durée
Chambre: Num. chambre, Prix
L'introduction de cette possibilité, surtout destinée à simplifier le plongement des MCD touffus, est discutée ici.
Il se fait en deux étapes:
Pour construire la représentation interne, l'algorithme de base réalise la séquence d'opérations suivante :
Remarque. Un couple de cardinalités non standard, c'est-à-dire distinct de (0,1), (1,1), (0,N) et (1,N), est traité comme (0,1) si son deuxième symbole est un 1, et comme (0,N) sinon. Cela couvre en particulier les cas (*, 1), (*,N), (?,?) et (X,X).
Pour construire la représentation externe, Mocodo formate la représentation interne à l'aide d'un gabarit. Près d'une centaine de gabarits sont fournis, qui permettent de produire quatre grandes catégories de résultats :
La transformation -t mld
opère la conversion d'un MCD (modèle conceptuel de données) en un MLD (modèle logique de données), autrement appelé schéma relationnel :
%mocodo -i ccp -t mld
Sous Jupyter Notebook, comme pour toutes les opérations de conversion, le tracé du MCD est omis par défaut. Dans le cas très fréquent où l'on a besoin de visualiser simultanément le MCD et le MLD, on peut invoquer l'option -t
sans arguments (ou encore --mld
) :
%mocodo -i ccp -t
La plupart des SGBD offrent une représentation hybride (graphique / texte) de la base sous la forme de tables liées par des flèches. Nous l'appelons diagramme relationnel. Sous Mocodo :
%mocodo -i ccp --colors mondrian -t diagram
Le nom du fichier généré avant rendu graphique se termine par _mld.mcd
. L'extension .mcd
signifie que Mocodo peut le prendre comme texte-source (bien que ce ne soit pas un schéma conceptuel). Examinons son contenu :
display.Code("ccp_mld.mcd", language="text")
La syntaxe d'un MLD est effectivement la même que celle d'un MCD, à ceci près que les associations sont remplacées par des liens allant de l'attribut a1
de l'entité E1
à l'attribut a2
de l'entité E2
, et notés : E1: ... a1 > E2 > a2
.
Les relations sont placées dans le même ordre que les boîtes du MCD d'origine. Vous devrez quelquefois les réarranger (automatiquement ou manuellement) pour obtenir un résultat plus esthétique. Notez que des boîtes invisibles ont été automatiquement insérées une colonne sur deux afin de laisser de la place aux flèches.
Limitation. Les clés étrangères composites sont actuellement représentées comme si elles étaient séparées (autant de flèches que de parties).
Nouveautés de la version 4.0.
E1: ... a1->E2->a2
se note maintenant E1: ... a1 > E2 > a2
._mld.mcd
au lieu de .mld
. L'ancienne extension est abandonnée.La principale raison de vivre d'un MCD est de se métamorphoser in fine en une chatoyante base de données relationnelles. Cela se fait au moyen d'un sous-ensemble du langage SQL appelé DDL (Data Definition Language). Sous Mocodo :
%mocodo -i ccp -t sql
Notez le NOT NULL
des clés primaires. Il s'agit d'une redondance, mais aussi d'une bonne pratique. Non seulement parce qu'explicit is better than implicit : elle peut se révéler utile, par exemple pour désactiver les contraintes de clé primaire pendant une maintenance tout en continuant à interdire le remplissage avec des NULL
. Si cela vous gêne, nous montrons en annexe comment l'éliminer.
Principales nouveautés de la version 4.0.
UNIQUE
, NOT NULL
et NULL
appropriées.Ref_client
.Avec l'option de réécriture -t create:types
Mocodo essaiera d'inférer des libellés des attributs tout type manquant. La langue définie avec l'option --language
est prioritaire, mais l'anglais prend la relève en cas d'échec.
%%mocodo -t create:types --select rw
Customer: Customer ID, Last Name, First Name, Address
Make Order, 0N Customer, 11 Order
Order: Order Number, Date, Amount
INCLUDE, 1N Order, 0N Product: Quantity
Product: Product ID, Description, Unit Price
Il va de soi que les types inférés devront être systématiquement contrôlés, et parfois corrigés ou complétés. Une discussion sur StackOverflow, Common MySQL fields and their appropriate data types, a servi de point de départ. La liste des types utilisée est celle de Wikipedia. Consultez les correspondances spécifiées dans mocodo/resources/default_datatypes_fr.tsv
, etc. pour plus de détails, et n'hésitez pas à ouvrir le débat si vous avez des corrections ou des suggestions.
Si vous préférez tout typer à la main, vous pouvez au moins créer les « cases » à remplir :
%%mocodo -t create:types=[] --select rw
Customer: Customer ID, Last Name, First Name, Address
Make Order, 0N Customer, 11 Order
Order: Order Number, Date, Amount
INCLUDE, 1N Order, 0N Product: Quantity
Product: Product ID, Description, Unit Price
L'argument sql
peut être remplacé par un nom de dialecte parmi mysql
, oracle
, postgresql
, sqlite
et (nouveauté de la version 4) mssql
. Quelques transformations seront alors appliquées au code-source généré. Du fait de l'uniformisation de la syntaxe apportée par la version 4, elles sont assez minimes.
Notez les points suivants :
USER
et MEMBER
sont réservés en MySQL. Les listes viennent du site modern-sql.com de Markus Winand, et plus précisément de la page https://modern-sql.com/reserved-words-empirical-list.b
, un boilerplate de création de la base est ajouté en préambule.%%mocodo -t mysql:b
USER: username, mail, member
Avec la sous-sous-option c
, Mocodo peut faire apparaître dès le niveau logique certaines contraintes du niveau physique. Les notations sont les suivantes :
Contrainte | niveau logique | niveau physique |
---|---|---|
non-optionalité | attribut! | NOT NULL |
optionalité | attribut? | NULL |
unicité | attribut $^{u1\ u2...}$ | UNIQUE |
Par exemple, ci-dessous, la clé étrangère _#Réfclient est maintenant marquée comme non optionnelle :
%mocodo -i ccp -t mld:c
La clé étrangère #id entreprise est marquée comme optionnelle :
%%mocodo --select all -t mld:c
Entreprise: id. entreprise, raison, activité, adresse
Envoyer, 0N Entreprise, 01 Participant
Participant: id. inscrit, nom, adresse
La clé étrangère #id employé est marquée comme unique :
%%mocodo --select all -t mld:c
EMPLOYÉ: id. employé, nom employé
DIRIGER, 11 DÉPARTEMENT, 01 EMPLOYÉ
DÉPARTEMENT: id. département, nom département
Les contraintes NOT NULL
ou NULL
spécifiées dans les types peuvent également faire l'objet d'une visualisation au niveau relationnel :
%%mocodo -t mld:c
Personne: id. personne [VARCHAR(8)], nom [VARCHAR(255) NOT NULL], prénom [VARCHAR(255)], nom de jeune fille [VARCHAR(255) NULL]
Pour les contraintes d'unicité, qui peuvent s'appliquer à plusieurs groupes d'attributs potentiellement non disjoints, la notation est un peu plus complexe. Voici un exemple proposé par Fabien Duchateau :
%%mocodo --select all -t mld:c --shapes trebuchet # changement de police de caractères pour mieux distinguer les 1 des I
CLIENT: Réf. client, 1_Nom, 1_Prénom, Adresse, 2_Mail
C'est l'occasion d'introduire quelques définitions :
Ainsi, dans l'exemple précédent, l'ensemble des identifiants candidats de CLIENT est constitué de :
Par défaut, dès la première déclaration d'un identifiant alternatif, Mocodo fait apparaître une gouttière à gauche des attributs de toutes les entités. Y sont portés :
La notation de Mocodo permet de faire de n'importe quels sous-ensembles d'attributs des identifiants alternatifs. Ci-dessous, le premier identifiant alternatif est le triplet (bar, biz, quux), le second (biz, buz, quux) et le troisième (qux, quux) :
%%mocodo --select all -t markdown:c sql --shapes trebuchet
FOO: foo, 1_bar, 12_biz, 2_buz, 3_qux, 123_quux
Examinons le cas exceptionnel où l'identifiant à souligner a un attribut commun avec un identifiant alternatif. Ce dernier devant être distinct et minimal, cela implique que l'identifiant est composite.
%%mocodo --shapes trebuchet
Entité 1_: 1_foo, _bar, 1_biz
Entité 2_: foo, 1_bar, 1_biz
Entité 3_: foo, 01_bar, 1_biz
1_foo
.1_bar
dénote déjà l'appartenance à un identifiant alternatif. Elle ne peut dénoter simultanément l'appartenance à l'identifiant à souligner.0
(entité 3).Un sous-cas demande encore réflexion : celui où le premier attribut ne fait pas partie de l'identifiant à souligner (entité 4). Si l'on veut alors que ce premier attribut appartienne à une clé alternative, il faut expliciter le 0
(entité 5).
%%mocodo --shapes trebuchet
Entité 40: _foo, _bar, biz
Entité 50: 01_foo, _bar, 1_biz
En résumé, on explicite le 0
, soit pour empêcher le soulignement du premier attribut, soit pour forcer le soulignement d'un attribut suivant.
Cela devrait vous rappeler quelque chose… Remplacez 0
par _
dans la phrase précédente et vous retrouverez la règle que vous avez appris à connaître et à aimer : on explicite le _
, soit pour empêcher le soulignement du premier attribut, soit pour forcer le soulignement d'un attribut suivant.
Dans ce joli exemple dû à Idris NEUMANN, Initiation à la conception de bases de données relationnelles avec MERISE, les renforcements successifs aboutissent à faire entrer l'identifiant de RUE dans celui de APPARTEMENT, alors même que ces entités sont séparées par non moins de trois associations :
%%mocodo -t
Appartement: num appart., nb pièces
Composer, 0N Étage, _11 Appartement
Étage: num étage, nb appartements
Appartenir, 1N Immeuble, _11 Étage
Immeuble: num immeuble, nb étages
Se situer, 0N Rue, _11 Immeuble
Rue: code rue, nom rue
Le résultat apparaît plus clairement sur le diagramme relationnel :
%mocodo -i sandbox -t diagram --colors mondrian
Une phase préliminaire de l'algorithme de passage au relationnel consiste à « renforcer » les entités faibles de façon à traiter uniquement des identifiants forts dans la suite. Cela permet la gestion des renforcements en cascade comme ci-dessus, ainsi que la détection des problèmes de renforcement cyclique :
%%mocodo
Pick, 0N Land, _11 Peer
Land: true, hold
Peer: foot, city
Zone, 1N Peer, _11 Land
%mocodo -i sandbox -t
La bonne gestion d'un héritage est primordiale, tant du point de vue de la préservation du patrimoine, que de l'optimisation des ressources financières, de la minimisation des conflits familiaux et du respect des dernières volontés du défunt. Je blague.
Adaptons ici un exemple d'un cours de Stéphane Crozat. Nous reprenons sa terminologie et donnons en parallèle celle introduite par Martin Fowler dans Patterns of Enterprise Application Architecture, Addison-Wesley (2003).
Ci-dessous, l'héritage est considéré comme total (tout document est soit un ouvrage, soit une thèse, soit les deux). Crozat passe en revue trois mécanismes possibles pour le passage au relationnel.
L'héritage par référence (en anglais, Class Table Inheritance ou Table Per Type Inheritance) se note en Mocodo par une flèche simple allant vers les filles. Une référence à la table-mère sera ajoutée dans chaque table-fille comme clé étrangère. L'intérêt de cette solution est en raison directe du nombre d'attributs non identifiants de l'entité-mère.
%%mocodo --select all -t mld:c
DOCUMENT: cote, titre, auteur
OUVRAGE: éditeur
/T\ DOCUMENT -> OUVRAGE, THÈSE
THÈSE: discipline, université
L'héritage par absorption dans les tables-filles (en anglais, Concrete Table Inheritance ou Table Per Concrete Inheritance) se note en doublant la flèche :
%%mocodo --select all -t mld:c
DOCUMENT: cote, titre, auteur
OUVRAGE: éditeur
/T\ DOCUMENT => OUVRAGE, THÈSE
THÈSE: discipline, université
L'héritage par absorption dans la table-mère (en anglais, Single Table Inheritance ou Table Per Hierarchy Inheritance) se note par une flèche simple allant vers la mère. Les tables-filles disparaissent, et leurs attributs migrent dans la mère avec une contrainte d'optionalité (point d'interrogation en relationnel, NULL
en SQL).
%%mocodo --select all -t mld:c sql
DOCUMENT: cote, titre, auteur
OUVRAGE: éditeur
/X\ DOCUMENT <- OUVRAGE, THÈSE: discriminateur [ENUM ('OUVRAGE', 'THÈSE')]
THÈSE: discipline, université
Ci-dessus, nous avons donné comme « attribut » au triangle d'héritage un « discriminateur » de type ENUM
. Cela ajoute à la table un champ optionnel ou non (selon que l'héritage est partiel ou total) permettant de déterminer à quel type concret d'une occurrence on a affaire.
C'est par défaut un UNSIGNED INT
, qui pourra prendre les valeurs :
Alternativement à l'emploi d'un discriminateur, Mocodo peut ajouter un drapeau booléen par table-fille. Cela se note en doublant la flèche :
%%mocodo --select all -t mld:c sql
DOCUMENT: cote, titre, auteur
OUVRAGE: éditeur
/T\ DOCUMENT <= OUVRAGE, THÈSE
THÈSE: discipline, université
Un agrégat simple autour d'une association dont toutes les cardinalités maximales sont N se traduit en relationnel comme la même association non agrégée, mais avec une clé primaire réduite :
%%mocodo --select all -t mld:c
DATE: date
RÉSERVER, /1N CLIENT, 1N CHAMBRE, 0N DATE: durée
CHAMBRE: num. chambre, prix
CLIENT: id. client, nom client
Un agrégat simple autour d'une association dont la cardinalité maximale « de sortie » est 1 se traduit en relationnel comme la même association non agrégée, mais avec une contrainte d'unicité sur la clé étrangère. Ci-dessous, au lieu d'avoir simplement num résa $\implies$ (num voilier, num semaine), on a donc en plus (num voilier, num semaine) $\implies$ num résa :
%%mocodo --select all -t mld:c
Voilier: num voilier, longueur
Offrir, /11 Réservation, 0N Voilier, 0N Semaine: tarif
Semaine: num semaine, date début
Réservation: num résa, arrhes, date résa
Le cas des agrégats multiples, plus rare, est étudié en annexe.
Le passage au relationnel supprime automatiquement les tables réduites à une clé primaire, pourvu qu'aucun composant de celle-ci ne soit clé étrangère. Si l'on souhaite maintenir certaines de ces tables, on préfixe d'un +
l'entité concernée. Ainsi, ci-dessous, Date est supprimée, mais pas Thème.
%%mocodo --select mld mcd -t mld:e
Animateur: num. animateur, nom animateur
Intervenir, 1N Animateur, 1N Formation, 1N Date: nb heures
Formation: id. formation, durée
Aborder, 1N Thème, 1N Formation
+Thème: thème
Date: date
:
Notez l'explication de la suppression (en NB) et celle de la perte du caractère étranger de l'attribut date (dans la table Intervenir). Pour une discussion sur cette problématique, cf. issue #66.
Une association de dépendance fonctionnelle ne donne normalement pas lieu à une création de table. Pour reprendre un exemple vu plus haut :
%%mocodo --select all -t mld:c
Entreprise: id. entreprise, raison, activité, adresse
Envoyer, 0N Entreprise, 01 Participant
Participant: id. inscrit, nom, adresse
Dans le cas où les particuliers sont beaucoup plus nombreux que les employés d'entreprise, la clé étrangère #id. entreprise est presque toujours à NULL
. C'est une perte d'espace de stockage. On peut entourer l'association de crochets droits préfixer d'un +
(à partir de la version 4) l'association pour forcer sa conversion en table. Mocodo produit alors une visualisation intermédiaire entre entité et association :
%%mocodo --select all -t mld:c --colors mondrian
Entreprise: id. entreprise, raison, activité, adresse
+Envoyer, 0N Entreprise, 01 Participant
Participant: id. inscrit, nom, adresse
Cela permet du même coup d'éviter un champ optionnel, dont la gestion peut être délicate (notamment sous Microsoft SQL Server qui, au mépris du standard SQL, ne semble pas convaincu qu'une colonne UNIQUE
peut contenir plus d'un NULL
!).
Ce MCD modélise la soutenance de stage des étudiants, ainsi que la visite d'amitié et de contrôle dont les honore leur enseignant responsable :
%%mocodo -t
Soutenir, 01 Étudiant, 0N Date: note stage
Étudiant: num. étudiant, nom, coordonnées
Date: date
Répondre de, 0N Date, 11 Étudiant, 0N Enseignant
Enseignant: num. enseignant, nom, coordonnées
Force est de constater que la table Étudiant laisse quelque peu à désirer du point de vue sémantique :
Ces précisions peuvent être apportées en insérant, entre la cardinalité et l'entité des pattes appropriées, une note entre crochets, appelée rôle. Ces rôles seront utilisés pour compléter le nom des clés étrangères correspondantes. Cela permet de réintroduire la sémantique perdue lors de la disparition des associations de dépendance fonctionnelle par lesquelles elle ont migré :
%%mocodo -t mld
Soutenir, 01 Étudiant, 0N [soutenance] Date: note stage
Étudiant: num. étudiant, nom, coordonnées
Date: date
Répondre de, 0N [+ visite resp] Date, 11 Étudiant, 0N [-num. ens. resp.] Enseignant
Enseignant: num. enseignant, nom, coordonnées
La composition du rôle est entièrement paramétrable :
+
en préfixe supprime le séparateur.-
en préfixe supprime le nom de la clé et le remplace par le rôle.Pour ne pas surcharger le dessin, le rôle n'est pas affiché à côté du lien, mais il apparaît au survol de la cardinalité.
Correction de la version 4.0. Dans une association réflexive hiérarchique, c'est désormais le rôle porté par la patte *N
qui sert à rétablir la sémantique. Auparavant c'était l'inverse, en contradiction avec le traitement des associations binaires et n-aires : si vous avez utilisé des rôles dans une association réflexive avant la version 4.0.0, vous devez donc les permutez pour que Mocodo les traite correctement. Reprenons la filiation patrilinéaire :
%%mocodo -t
HOMME: num. SS, nom, prénom
ENGENDRER, 0N [père] HOMME, 01 [fils] HOMME
Lorsque toutes les cardinalités d'une dépendance fonctionnelle sont 11 (ou toutes 01), le sens de migration est spécifié à coût zéro en référençant l'entité réceptrice en tête de la liste des entités énumérées dans la clause de définition de l'association :
%%mocodo -t mld diagram sql --colors mondrian
USER: user id [VARCHAR(8)], name [VARCHAR(100)], pseudo [VARCHAR(100)]
DF, 11 USER, 11 AUTHENTICATION
AUTHENTICATION: email [VARCHAR(255)], password hash [BINARY(64)], salt [BINARY(16)]
Dans la version avec identification relative, c'est l'entité faible qui doit être placée en tête :
%%mocodo -t mld diagram sql --colors mondrian
USER: user id [VARCHAR(8)], name [VARCHAR(100)], pseudo [VARCHAR(100)]
DF, _11 AUTHENTICATION, 11 USER
AUTHENTICATION: email [VARCHAR(255)], password hash [BINARY(64)], salt [BINARY(16)]
Les traitements alternatifs (fusion en une seule table ou migration dans les deux sens) ne sont pas pris en charge par Mocodo. La dernière pratique ressortit à la phase d'optimisation et de dénormalisation de la base, qui est en dehors de sa juridiction. La seule chose que vous pouvez faire, à des fins d'illustration, est de reprendre le MLD généré pour y ajouter à la main la migration inverse. Notez cependant que les schémas logique et physique générés seront alors dépourvus de toute clé étrangère (et nécessiteront donc également d'être retouchés à la main).
%%mocodo -t mld sql --colors mondrian --select all
:
USER: user id [VARCHAR(8)], name [VARCHAR(100)], pseudo [VARCHAR(100)], #email > AUTHENTICATION > email
:
AUTHENTICATION: email [VARCHAR(255)], password hash [BINARY(64)], salt [BINARY(16)], #user id > USER > user id
:
La table A dépend de la table B lorsque A possède une clé étrangère qui est clé primaire de B. Cette notion est utile dans le cas où l'on doit importer une base de données à partir d'un ensemble de fichiers CSV (ou autres). Si l'on veut éviter de perdre le bénéfice du contrôles de clés étrangères (en faisant, p. ex. sous MySQL, SET FOREIGN_KEY_CHECKS = 0
), il conviendra de lire ces fichiers dans un ordre topologique quelconque. Mocodo peut générer un graphe des dépendances qui met cet ordre en évidence :
%mocodo -i ccp -t dependencies --defer
Même si un tel graphe n'est pas forcément sans circuits, remplir les tables dans le sens de lecture des langues latines minimisera le recours à la désactivation des contraintes de clés étrangères.
D'après son site officiel :
DBML (Database Markup Language) est un DSL (langage dédié) open-source conçu pour définir et documenter les schémas et structures de base de données. Il vise la simplicité, la cohérence et la lisibilité.
Mocodo parle maintenant DBML :
%mocodo -i ccp -t dbml --title CCP
À notre connaissance, il n'existe pas actuellement d'API publique de rendu des diagrammes DBML. Pour les visualiser, copiez-collez la sortie sur Dbdiagram.io, ou installez un plugin VS-Code :
display.SVG("../examples/dbml.svg")
D2 est un langage de description de diagrammes de différents types. La prise en charge des diagrammes relationnels est minimale, mais le projet est jeune (actuellement en version 0.6.1, open source depuis novembre 2022). Son point fort est TALA, son algorithme de plongement propriétaire, que vous pouvez tester ici. Celui-ci requérant une licence payante, si vous déférez le rendu, c'est le plongement par défaut (Dagre, celui de Mermaid) qui sera utilisé.
%mocodo -i ccp -t d2
%mocodo -i ccp -t d2 --defer
À tout seigneur tout honneur, Mocodo peut traduire votre MCD en UML. Ce formalisme graphique n'a, curieusement, pas de DSL textuel officiel. Nous nous rabattons donc sur le standard de fait, PlantUML :
%mocodo -i ccp --title CCP -t uml:plantuml=- # '-' supprime un préambule par défaut qui ne nous intéresse pas ici
%mocodo -i ccp -t uml --defer --colors brewer+5
Nouveauté de la version 4.0. Force est de reconnaître que de nos jours, les MCD à la sauce Merise ne sont plus goûtés que par une poignée d'irréductibles Gaulois (et contractuellement leurs étudiants). Dans le cadre de son projet secret de domination planétaire, Mocodo commence à faire du pied à des notations mieux comprises du reste de l'univers.
Un MCD peut être converti en un ERD (Entity-Relationship Diagram) dans la notation de Chen, sans ses attributs ou avec :
%mocodo -i ccp -t chen --defer --colors ocean
%mocodo -i ccp -t chen:attrs --defer --colors ocean
Dans le même ordre d'idées, Mocodo peut générer des ERD dans l'astucieuse notation introduite en 1976 par Gordon Everest. Par défaut, le format du fichier intermédiaire est là encore Graphviz :
%mocodo -i ccp -t crow --defer --colors brewer+3
Il est également possible de demander une sortie au format Mermaid. Vous en avez un exemple dans l'introduction, nous ne le répétons pas ici. Le DSL de Mermaid est de plus haut niveau, non encombré d'informations de style. Cependant, le format Graphviz peut être préféré pour plusieurs raisons :
DECIMAL(10,2)
en DECIMAL(10-2)
) ;--seed
) ;Vous pouvez extraire sous forme de table diverses informations sur les attributs de votre MCD.
Un format possible est TSV. Dans ce cas, sous Jupyter Notebook, si la bibliothèque pandas
est installée, elle sera rendue comme un dataframe :
%mocodo -i ccp -t data_dict:tsv
Le format par défaut est Markdown. Vous pouvez préciser en sous-sous-option tout ou partie des colonnes suivantes dans l'ordre où vous les souhaitez :
label
: le libellé de l'attribut ;type
: son type ou un descriptif (auquel cas il conviendra de changer le nom de la colonne) ;box
: le nom de l'entité ou association où il se trouve.Entourez ces noms de colonnes de balises Markdown pour les mettre en forme (pas d'incidence en TSV). Faites-les suivre de ="Nom de colonne personnalisé"
pour éviter la valeur par défaut (dépendante de l'option language
). Dans l'exemple ci-dessous, les sous-sous-options se décodent ainsi :
**box**="Entité ou association"
: boîtes en colonne 1, en-tête personnalisé, cellules en gras ;label
: libellé des attributs en colonne 2 ;type
`=
`Type
` : types en colonne 3, en-tête personnalisé et cellules dans une police non proportionnelle.%mocodo -i ccp -t data_dict:**box**="Entité ou<br>association",label,`type`=`"Type de données"`
Aménités.
%mocodo -i ccp -t data_dict:label
Nouveautés de la version 4.0.
Vous pouvez demander à encoder le texte-source de votre MCD dans un lien vers Mocodo online, qui le composera automatiquement dans la zone d'entrée :
%mocodo -i ccp -t share
Un chiffre ou tiret bas à la fin du nom d'une boîte (entité ou association) est utilisé en interne pour distinguer cette boîte des autres, mais n'est pas affiché dans le diagramme conceptuel. Cela peut servir à produire une vue en extension d'un MCD.
Voici par exemple le MCD que j'utilise en cours pour introduire la notion d'entité faible (à gauche, vue en compréhension, à droite vue en extension):
%%mocodo
ŒUVRE1: cote, titre, date de publication
:::
ŒUVRE2: 612.NAT.34, J'apprends à lire à mes souris blanches, mai 1975
:
DF, 1N ŒUVRE1, _11 EXEMPLAIRE1
::
DF, XX ŒUVRE2, XX EXEMPLAIRE2
DF, XX ŒUVRE2, XX EXEMPLAIRE3
DF, XX ŒUVRE2, XX EXEMPLAIRE4
EXEMPLAIRE1: numéro d'exemplaire, état, date d'achat
::
EXEMPLAIRE2: 1, bon état, 12/6/1975
EXEMPLAIRE3: 2, bon état, 1/8/1977
EXEMPLAIRE4: 3, reliure rongée, 3/4/2005
Mocodo n'interdit pas la conversion en relationnel d'un tel MCD, mais celle-ci n'a aucun sens.
Si l'on veut garder les cardinalités sans les afficher, on peut les préfixer d'un -
. Le résultat de la conversion en relationnel peut alors être interprété comme l'ensemble des lignes des différentes tables.
%%mocodo -t
ŒUVRE: 612.NAT.34, J'apprends à lire à mes souris blanches, mai 1975
DF, -1N ŒUVRE, -_11 EXEMPLAIRE1
DF, -1N ŒUVRE, -_11 EXEMPLAIRE2
DF, -1N ŒUVRE, -_11 EXEMPLAIRE3
EXEMPLAIRE1: 1, bon état, 12/6/1975
EXEMPLAIRE2: 2, bon état, 1/8/1977
EXEMPLAIRE3: 3, reliure rongée, 3/4/2005
Les débutants ont souvent des doutes sur la sémantique de telle ou telle cardinalité. Cette information peut être incluse dans le texte-source en annotant les pattes correspondantes. Survolez les cardinalités du MCD ci-dessous pour faire apparaître leur description.
%%mocodo
Produit: réf. produit, libellé, prix unitaire
Inclure, 1N [Une commande inclut au moins un produit.] Commande, 0N [Un produit peut être commandé un nombre quelconque de fois.] Produit: quantité
Commande: num. commande, date, montant
DF, 0N [Un client peut passer zéro (prospect) ou plusieurs commandes.] Client, 11 [Une commande est passée par un et un seul client.] Commande
Client: réf. client, nom, adresse
Parrainer, 01 [Un client peut avoir été parrainé ou non.] Client, 0N [Un client peut parrainer d'autres clients.] Client : date parrainage
Remarquez que la syntaxe est la même que pour les rôles, qui sont en plus utilisés lors du passage au relationnel. Comment Mocodo fait-il la différence ? En appliquant les règles suivantes :
+
ou -
, c'est un rôle.Le même principe s'applique aux contraintes (survolez le Ⓘ) :
%%mocodo
Projet: num. projet, nom projet
:
Fournir, 1N Projet, 1N Pièce, 1N Société: quantité
Société: num. société, raison sociale
Requérir, 1N Projet, 0N Pièce: quantité
:
Pièce: réf. pièce, libellé pièce
(I) [Toute pièce fournie doit avoir été requise.] ..Pièce, ->Requérir, --Fournir, Projet
Limitations.
Nouveauté de la version 3. Il est possible de faire apparaître progressivement les différentes « boîtes » constituant un MCD. Pour cela, il suffit d'indenter (décaler vers la droite à l'aide d'espaces ou de tabulations) au moins une ligne. Les éléments correspondants seront alors répartis sur autant de « calques » qu'il y a de niveaux d'indentations.
Voici par exemple un exercice consistant en la description du « réel perçu » d'une entreprise de VPC :
- Un produit est connu par une référence, un libellé et un prix unitaire.
- Toute commande inclut un produit ou plusieurs, chacun en une certaine quantité.
- Un client peut passer zéro (client potentiel) ou plusieurs commandes.
- Un client peut entrer dans la base par parrainage d'un autre client.
L'enseignant peut le présenter pas à pas en suivant les étapes de l'énoncé :
%%mocodo --colors ocean
Parrainer, 01 Client, 0N Client : date parrainage
Produit: Réf. produit, Libellé, Prix unitaire
Inclure, 1N Commande, 0N Produit: Quantité
Client: Réf. client, Nom, Prénom, Adresse
DF, 0N Client, 11 Commande
Commande: Num. commande, Date, Montant
Remarques.
Pour ajouter facilement de l'interactivité à un MCD existant :
Depuis la version 4.0, l'éditeur de Mocodo online vous permet de créer des curseurs multiples, ce qui simplifie encore ces opérations.
Limitations.
Éviter qu'une interaction sur un SVG ne s'applique à un autre.
Dans le cas très rare où plusieurs SVG interactifs générés à partir du même texte-source coexistent sur une même page web, une interaction opérée sur l'un s'applique également à tous les autres. Par exemple, cliquer sur l'un des ronds gris de l'une des figures ci-dessous agira sur les deux figures :
%%mocodo
FOO: foo
BAR: bar
%%mocodo
FOO: foo
BAR: bar
Ce problème trahit une « collision » : différents éléments du DOM se sont vus attribuer la même empreinte (obtenue par hachage du texte-source). La solution est de passer un entier discriminant qui, par concaténation, fera de ces empreintes de véritables identifiants.
%%mocodo --uid_suffix 1
FOO: foo
BAR: bar
%%mocodo --uid_suffix 2
FOO: foo
BAR: bar
Les gabarits de conversion en MLD (à savoir html
, markdown
, latex
et text
) admettent une sous-sous-option e
qui accompagne le résultat par des explications détaillées du mécanisme de passage :
%mocodo -i ccp -t markdown:e
Nous avons essayé d'être aussi précis que possible, tout en « factorisant » avec soin les lignes consécutives suseptibles de l'être. Vous pouvez adapter ces explications à votre enseignement en modifiant une copie du gabarit html-ce.yaml
, dont les autres sont dérivés.
Les MCD à trous sont des exercices classiques d'introduction aux bases de données.
Pour éviter le marquage automatique du premier attribut d'une entité comme identifiant, il suffit de le préfixer par un tiret bas (_
) : ce caractère est donc un commutateur, qui souligne un attribut non souligné par défaut, et désouligne un attribut souligné par défaut.
%%mocodo
CLIENT: _Réf. client, Nom, Prénom, Adresse
PASSER, 0N CLIENT, 11 COMMANDE
COMMANDE: _Num. commande, Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
PRODUIT: _Réf. produit, Libellé, Prix unitaire
Vous pouvez masquer n'importe quelles cardinalités en les remplaçant par XX
ou en les préfixant d'un -
:
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, XX CLIENT, XX COMMANDE
COMMANDE: Num. commande, Date, Montant
INCLURE, -1N COMMANDE, -0N PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Nouveauté de la version 4.0. Si la cardinalité comporte un et un seul X
, l'autre caractère sera affiché tout seul.
Vous pouvez mettre deux virgules consécutives pour réserver la place d'un attribut manquant. Les espaces insécables sont préservés, ce qui permet de réserver plus d'espace horizontal, cf. ci-dessous premier attribut vide de INCLURE.
%%mocodo
CLIENT: Réf. client,,,
PASSER, XX CLIENT, XX COMMANDE
COMMANDE: , Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité,,,,
PRODUIT: Réf. produit, Libellé, Prix unitaire
Régression de la version 4.0. Les espaces insécables ne sont plus préservés. Il n'y a donc plus d'autre moyen de réserver davantage d'espace horizontal que d'employer le style blank
(paragraphe suivant).
Vous pouvez transformer en exercice à trous n'importe quel MCD en rendant complètement transparentes les couleurs des attributs, associations et cardinalités. Le style blank
a été prédéfini à cet effet:
%mocodo -i ccp --colors=blank
Attention, n'utilisez cette méthode que pour la projection : l'information textuelle est toujours présente, susceptible d'être sélectionnée et collée ailleurs. Vous pouvez bien sûr empêcher cette possibilité en convertissant le SVG en PNG, mais le plus simple est d'appliquer une réécriture empty
:
%mocodo -i ccp -t empty # équivalent de "delete:types,notes,attrs,cards"
Obfusquer un MCD consiste à vider celui-ci de sa sémantique de surface en substituant des chaînes aléatoires à tous les libellés. Cela permet de créer des exemples d'illustration de telle ou telle notion « pure » sans risquer de voir son public se focaliser sur des détails-métier (c'est l'équivalent de la variable méta-syntaxique foobar
dans le contexte de la pédagogie de la programmation).
%mocodo -i ccp --seed=1 --select mcd -t obfuscate # raccourci pour "obfuscate:labels"
En argument, vous pouvez ajouter le chemin d'un fichier texte quelconque où puiser les mots de substitution. Par exemple, le texte du README
de ce projet :
%mocodo -i ccp -t obfuscate:labels=../../README.md --seed=1 --select mcd
Mocodo essaie d'abord de trouver ce fichier à l'endroit indiqué. En cas d'échec, il le cherche (avec extension .txt
facultative) parmi ceux distribués avec le logiciel, à savoir:
"lorem.txt"
(6464 mots) : le faux-texte le plus courant, augmenté d'une sélection des 10000 mots latins les plus courants compilés par Kyle P. Johnson, le tout privé de ses doublons et des mots de moins de 3 lettres ("lorem_ipsum.txt"
avant la version 4.0)."fr.txt"
(3396 mots) : une liste des 4000 mots français les plus courants, privée de ceux comportant une apostrophe ou moins de 4 lettres. Source : http://wortschatz.uni-leipzig.de/index.html via Wikitionary. Nouveauté de la version 4.0."fr5.txt"
(464 mots): la liste de "fr.txt"
, restreinte aux mots de 5 lettres. Nouveauté de la version 4.0."en4.txt"
(640 mots): une sélection (SFW) de mots anglais de quatre lettres ("four_letter_words.txt"
avant la version 4.0)."disparition.txt"
(7489 mots) : le lexique du célèbre roman lipogrammatique de Georges Perec, privé des mots de moins de 4 lettres.En cas de nouvel échec, il se rabat sur "lorem.txt"
.
NB. L'algorithme s'assure que la distance de Damerau-Levenshtein entre deux libellés de substitution quelconques est d'au moins 3. En clair, cela signifie que, si vous donnez en examen un exercice de conversion en relationnel basé sur un tel MCD, les erreurs de transcription d'un étudiant stressé, inattentif, illettré, dyslexique, roublard, ou tout cela à la fois, ne devraient pas vous empêcher de lui octroyer les points qui lui reviennent.
Vous pouvez créer un MCD partiellement aléatoire à partir d'un MCD donné en lui ajoutant un nombre n
d'associations (avec les entités nécessaires) :
%mocodo -i ccp -t grow:n=4 arrange --seed=1 --select mcd
Des sous-options pré-définies (données ci-dessous avec leur valeur par défaut après le =
) permettent de spécifier finement le nombre désiré :
arity_1=2
) ;arity_3=2
) ;arity_4=0
) ;doubles=1
) ;composites=1
) ;ent_attrs=4
) ;assoc_attrs=2
).On ne peut pas préciser directement le nombre d'associations binaires : si le nombre total des autres associations spécifiées n'arrivent pas à n
, elles viennent en complément.
Des sous-options de forme plus ou moins libre décrivent les cardinalités. Par exemple, _11-*N=2
créera deux entités faibles et /*N-*N
un agrégat. Les associations de complément sont *N-*N
.
Avec la sous-option from_scratch
, le MCD de départ est vide. À titre d'exemple, voici la transformation complexe invoquée par Mocodo online pour créer un MCD d'entraînement à la conversion au relationnel, accompagné de cette dernière. Notez la création de rôles par défaut : ils permettent de simuler le rétablissement de la sémantique des associations disparues.
%mocodo --seed=2 --mld -t grow:from_scratch,arity_3=1,_11-*N=1 obfuscate create:roles lower:roles arrange
Il n'est pas impossible que le MCD résultant soit incorrect (p. ex., apparition d'une identification relative circulaire), mais les contrôles effectués a priori et a posteriori devraient dans la majorité des cas produire quelque chose de raisonnable.
Impressionnez votre public en accompagnant l'option -t share
de --defer
:
%mocodo -i ccp -t share --defer