%reload_ext mocodo
from IPython import display
from pathlib import Path
Mocodo est un logiciel d'aide à l'enseignement et à la conception des bases de données relationnelles.
Ci-dessous, un exemple d'utilisation sous Jupyter Notebook. L'appel du programme est en première ligne, sur un texte d'entrée donné lignes suivantes. Le cas est adapté de l'article fondateur de Peter Chen, The entity-relationship model—toward a unified view of data (ACM Trans. Database Syst. 1, 1, March 1976, pp. 9–36). En sortie, le MCD (diagramme conceptuel) et le MLD (schéma relationnel) correspondants :
%%mocodo --mld --colors ocean --shapes copperplate --relations diagram markdown_data_dict
Ayant-droit: nom ayant-droit, lien
Diriger, 0N Employé, 01 Projet
Requérir, 1N Projet, 0N Pièce: qté requise
Pièce: réf. pièce, libellé pièce
Composer, 0N [composée] Pièce, 0N [composante] Pièce: quantité
DF1, _11 Ayant-droit, 0N Employé
Employé: matricule, nom employé
Projet: num. projet, nom projet
Fournir, 1N Projet, 1N Pièce, 1N Société: qté fournie
Département: num. département, nom département
Employer, 11 Employé, 1N Département
Travailler, 0N Employé, 1N Projet
Société: num. société, raison sociale
Contrôler, 0N< [filiale] Société, 01 [mère] Société
(I) ..Pièce, ->Requérir, --Fournir, Projet
L'appel précédent a également construit le dictionnaire des données:
display.Markdown("mocodo_notebook/sandbox_data_dict.md")
Ainsi que le diagramme relationnel, qui peut être visualisé par un nouvel appel:
%mocodo --input mocodo_notebook/sandbox.mld --colors desert
Exécutez ensuite sous un terminal la ligne suivante pour installer Mocodo ainsi que sa « commande magique » (utilisable sous Jupyter notebook) :
python -m pip install mocodo
Si vous souhaitez générer des figures en PDF ou en PNG :
python -m pip install cairosvg
Toujours sous un terminal, tapez:
mocodo
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:
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, évaluez une cellule avec:
%%mocodo
MISSION: accomplie
Pour charger automatiquement mocodo
à chaque ouverture d'un notebook (ce qui dispense d'évaluer %load_ext mocodo
) :
exécuter sous un terminal :
ipython profile create
éditer le fichier créé (p. ex.: ~/.ipython/profile_default/ipython_config.py
) pour remplacer les lignes suivantes :
## A list of dotted module names of IPython extensions to load.
#c.InteractiveShellApp.extensions = []
par celles-ci :
## A list of dotted module names of IPython extensions to load.
c.InteractiveShellApp.extensions = [
"mocodo",
]
Une fois Python installé, tapez sous un terminal:
python -m pip install mocodo
Vous ne bénéficierez pas de Jupyter Notebook, mais vous pourrez utiliser Mocodo en ligne de commande.
Vous pouvez utiliser Mocodo :
Faites pointer votre navigateur sur www.mocodo.net : vous pouvez commencer à taper votre MCD. Appuyez à tout moment sur le bouton de génération pour visualiser le diagramme conceptuel et en déduire les relations. Une fois que 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, installez Mocodo sur votre machine.
Tout a été fait pour faciliter au maximum la prise en main. Ainsi, pour peu que vous sachiez lancer une console (cmd
sous Windows, Terminal sous macOS), il vous suffit d'y entrer:
mocodo
Invoqué sous cette forme, le script 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 selon vos besoins avant de relancer la commande.
La commande mocodo
admet de nombreux arguments optionnels. Voici la traduction en français de la liste affichée par l'argument --help
. Destinée à servir de référence, elle peut être sautée sans inconvénient à la première lecture. Nous avons ajouté des liens vers des exemples d'utilisation dans ce document ; notez cependant que les %%
ou %
qui préfixent la « commande magique » mocodo
doivent être omis de la ligne de commande.
--help
.
Affiche un message d'aide, puis termine.--version
.
Affiche le numéro de version, puis termine.--language CODE
.
Outrepasse la localisation automatique des messages avec le code de langage donné (p. ex., fr
, en
, ...) (défaut: langue du système).--restore
.
Recrée une version originelle des fichiers sandbox.mcd
et params.json
dans le répertoire d'entrée, puis termine (défaut: False
).--params_path PATH
.
Le chemin du fichier de paramètres. S'il est omis, utilise params.json
dans le répertoire d'entrée. Si ce fichier n'existe pas, utilise les paramètres par défaut (défaut: params.json
).--input PATH
.
Le chemin du fichier d'entrée. Les fichiers de sortie seront par défaut générés dans le même répertoire (défaut: sandbox.mcd
). --output_dir PATH
.
Le répertoire où générer les fichiers de sortie (défaut: le répertoire où se trouve le fichier d'entrée). --encodings [STR [STR ...]]
.
Un ou plusieurs encodages à essayer successivement pour lire le fichier d'entrée (défaut: utf8
, puis encodage historique de la plateforme).--pdf
.
Génère une version PDF de la sortie graphique (requiert CairoSVG).--png
.
Génère une version PNG de la sortie graphique (requiert CairoSVG).--print_params
.
Affiche le contenu du fichier de paramètres, puis termine (défaut: False
).--reuse_geo
.
Utilise le fichier de géométrie généré lors de la précédente exécution.--uid_suffix
Permet de distinguer les éléments interactifs entre plusieurs SVG d'un même diagramme.--df STR
.
Acronyme à encercler dans une dépendance fonctionnelle (défaut: DF
).--card_format STR
.
Chaîne de format pour les cardinalités minimale et maximale (défaut: {min_card},{max_card}
).--strengthen_card STR
).
Chaîne pour les cardinalités relatives (défaut: _1,1_
).--flex FLOAT
.
Infléchit les pattes rectilignes dont les cardinalités sont susceptibles de collision (défaut: 0.75
).--colors PATH
.
Palette de couleurs à utiliser lors de la génération du dessin. Nom (sans extension) d'un fichier du répertoire colors
, ou chemin vers un fichier personnel (défaut: bw
).--shapes PATH
.
Spécification des polices, des dimensions, etc. Nom (sans extension) d'un fichier du répertoire shapes
, ou chemin vers un fichier personnel (défaut: dépendant de votre système).--scale SCALE
.
Facteur d'échelle multiplicatif (défaut: 1.0
).--adjust_width SCALE
.
Facteur multiplicatif appliqué à la largeur des libellés (défaut: 1.0
).--hide_notes
.
Ignore le survol des éléments annotés (défaut: False
).--detect_overlaps
.
Lève une erreur en présence de chevauchement de pattes horizontales ou verticales.--relations [NAME [NAME ...]]
.
Un ou plusieurs gabarits pour les schémas relationnels générés. Cf. répertoire relation_templates
(défaut: html text
).--disambiguation {numbers_only,notes}
.
Méthode de désambiguïsation des attributs migrants homonymes (défaut: notes
).--title STR
.
Nom de la base (utilisé pour la sortie SQL) (défaut: Sans titre
).--guess_title
.
Utiliser le nom de l'entité la plus référencée comme titre (défaut: False
).--arrange [{bb,ga}]
.
Met en page le diagramme, soit par séparation et évaluation (branch and bound), soit avec un algorithme génétique (genetic algorithm), puis termine (défaut: None
).--timeout SECONDS
.
Limite la durée du calcul de la mise en page (défaut: None
).--verbose
.
Affiche des détails oiseux lors du réarrangement (défaut: False
).--flip {h,v,d}
.
Affiche une version retournée horizontalement / verticalement / diagonalement du texte d'entrée, puis termine (défaut: None
).--fit [INT]
.
Reformate le texte d'entrée dans la ième plus petite grille possible, puis termine (défaut: None
).--obfuscate [PATH]
).
Affiche une version du texte d'entrée vidée de sa sémantique, puis termine. Cf. répertoire lorem
(défaut: None
).--obfuscation_max_length INT
).
Longueur maximale des mots de substitution (défaut: None
).--obfuscation_min_distance INT
).
Distance de Damerau Levenshtein minimale entre deux mots de substitution (défaut: 3).--seed FLOAT
.
Valeur du germe du générateur aléatoire (défaut: None
).Sous-options accessibles avec l'option --arrange=bb
.
--call_limit INT
.
Nombre maximal d'appels pour une boîte de départ donnée (défaut: 10000
).--min_objective INT
.
Meilleur objectif esthétique pour la mise en page (défaut: 0
).--max_objective INT
.
Pire objectif esthétique pour la mise en page (défaut: 15
).--organic
.
Réarrangement non limité à la grille originelle (défaut: False
).Sous-options accessibles avec l'option --arrange=ga
.
--population_size INT
.
Nombre d'individus à faire évoluer (défaut: 1000
).--crossover_rate RATE
.
Taux de croisement, entre 0 et 1 (défaut: 0.9
).--mutation_rate RATE
.
Taux de mutation, entre 0 et 1 (défaut: 0.06
).--sample_size INT
.
Taille de l'échantillon pour les tournois (défaut: 7
).--max_generations INT
.
Nombre maximal de générations (défaut: 300
).--plateau INT
.
Nombre maximal de générations consécutives sans amélioration (défaut: 30
).Ignorées lors de l'appel en ligne de commande.
Pour éviter d'avoir à invoquer Mocodo répétitivement avec une longue kyrielle d'options, vous pouvez mettre celles-ci une fois pour toutes dans un fichier params.json
situé dans le répertoire de lancement de Mocodo. La commande:
mocodo --restore
... le fait pour vous avec un fichier de paramètres vide, i.e. , un fichier-texte réduit aux deux caractères {}
(attention, elle rétablit aussi le fichier sandbox.mcd
à son contenu par défaut). Vous êtes encouragés à modifier ce fichier de paramètres selon vos goûts et vos besoins. De la sorte, le style de vos MCD pourra être maintenu à moindre frais à travers tous vos documents. En cas de besoin, vous pourrez toujours ponctuellement passer outre ces réglages en en précisant d'autres en ligne de commande. Plus précisément, chaque paramètre est déterminé:
--params_path
;params.json
du répertoire courant;Si vous lancez Mocodo avec l'option --print_params
, la valeur courante de l'ensemble des paramètres sera affichée. Vous pouvez envoyer la sortie dans un fichier params.json
et la modifier à votre gré pour une prise en compte lors du lancement suivant.
Elle nécessite l'installation de l'extension notebook mocodo
, laquelle doit en outre être rechargée à chaque ouverture (%reload_ext mocodo
, cf. première cellule du présent document). On a ainsi déclaré une « commande magique » mocodo
qui sera invoquée en la préfixant:
%%
pour prendre toutes les lignes suivantes de la cellule comme texte d'entrée du MCD ;%
si l'on récupère l'entrée ailleurs (avec --input
), ou qu'on n'en a pas besoin (p. ex., --help
ou --print_params
).À part ça, la syntaxe est généralement la même qu'en ligne de commande, ce qui devrait faciliter le passage de l'un à l'autre.
Il peut être utile de comprendre ce qui se passe en coulisses lorsque l'on invoque la commande magique sur une cellule:
mocodo_notebook
;sandbox.mcd
;sandbox.svg
, sandbox.html
, etc.;--no_mcd
); avec l'option --mld
, le schéma relationnel est également affiché au-dessous (au format HTML);--arrange
, --flip
, --obfuscate
, ...), Mocodo est automatiquement relancé sur celle-ci, permettant de visualiser le diagramme et/ou le schéma relationnel correspondants.Tous les fichiers peuvent être lus dans le répertoire mocodo_notebook
(commande magique %load
, mise en commentaire dans ce notebook pour éviter de recharger le fichier à chaque exécution).
Les trois exemples de l'introduction illustrent plusieurs de ces techniques usuelles:
%%mocodo --mld --colors ocean --shapes copperplate --relations diagram markdown_data_dict
... invoque le programme en demandant l'affichage du diagramme conceptuel (implicitement), du schéma relationnel (avec --mld
), des changements de style (avec --colors
et --shapes
) et la production d'un diagramme relationnel (--relations diagram
) et d'un dictionnaire de données (markdown_data_dict
). Le contenu de celui-ci est rechargé et visualisé à l'aide de la commande suivante:
%load mocodo_notebook/sandbox_data_dict.md
Tandis que le diagramme relationnel (MLD) est tracé en relançant Mocodo dessus:
%mocodo --input mocodo_notebook/sandbox.mld --colors desert
Nouveauté de la version 2.0.20 (contribution de Thomas Giro). Avec les options --arrange
, --flip
et --obfuscate
le résultat de l'évaluation de la cellule est un nouveau MCD, normalement affiché au-dessous. Ajoutez l'option --replace
pour substituer ce MCD au contenu de la cellule. Réévaluez alors celle-ci pour tracer le MCD résultant, ou annulez la dernière opération pour revenir au contenu originel.
Par exemple, l'évaluation de la cellule suivante:
%%mocodo
PRODUIT: Réf. produit, Libellé, Prix unitaire
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
COMMANDE: Num commande, Date, Montant
PASSER, 0N CLIENT, 11 COMMANDE
CLIENT: Réf. client, Nom, Prénom, Adresse
... remplacerait celle-ci par celle-là:
%%mocodo
PRODUIT: Réf. produit, Libellé, Prix unitaire
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
COMMANDE: Num commande, Date, Montant
PASSER, 0N CLIENT, 11 COMMANDE
CLIENT: Réf. client, Nom, Prénom, Adresse
Si vous voulez éviter de préciser à chaque fois les mêmes arguments (par exemple un changement de couleurs), vous pouvez placer un fichier params.json
dans le répertoire mocodo_notebook
. Mocodo peut même vous aider à le faire en exécutant la cellule suivante:
# You may edit and run the following lines
import json, pathlib
params = """
{
"adjust_width": 1,
"arrange": null,
"call_limit": 10000,
"card_format": "{min_card},{max_card}",
"colors": "bw",
"crossover_rate": 0.9,
"df": "DF",
"disambiguation": "notes",
"encodings": [
"utf8",
"macroman"
],
"fit": null,
"flex": 0.75,
"flip": null,
"guess_title": false,
"hide_notes": false,
"input": "mocodo_notebook/sandbox.mcd",
"language": "fr",
"max_generations": 300,
"max_objective": 15,
"min_objective": 0,
"mld": false,
"mutation_rate": 0.06,
"no_mcd": false,
"obfuscate": null,
"obfuscation_min_distance": 3,
"organic": false,
"output_dir": "mocodo_notebook",
"pdf": false,
"plateau": 30,
"png": false,
"population_size": 1000,
"print_params": false,
"relations": [
"html"
],
"replace": false,
"restore": false,
"reuse_geo": false,
"sample_size": 7,
"scale": 1,
"seed": null,
"shapes": "copperplate",
"strengthen_card": "_1,1_",
"timeout": null,
"title": "Sans titre",
"verbose": false
}
"""
try:
json.loads(params)
except:
raise RuntimeError("Invalid JSON. Check your syntax on https://jsonlint.com.")
pathlib.Path("mocodo_notebook/params.json").write_text(params.strip(), encoding="utf8");
Son évaluation remplace son propre contenu par des lignes de code similaires à:
# You may edit and run the following lines
import json, pathlib
params = """
{
"adjust_width": 1,
"arrange": null,
"call_limit": 10000,
"card_format": "{min_card},{max_card}",
"colors": "bw",
"crossover_rate": 0.9,
"df": "DF",
"disambiguation": "notes",
"encodings": [
"utf8",
"macroman"
],
"fit": null,
"flex": 0.75,
"flip": null,
"guess_title": false,
"hide_notes": false,
"input": "mocodo_notebook/sandbox.mcd",
"language": "fr",
"max_generations": 300,
"max_objective": 15,
"min_objective": 0,
"mld": false,
"mutation_rate": 0.06,
"no_mcd": false,
"obfuscate": null,
"obfuscation_max_length": null,
"obfuscation_min_distance": 3,
"organic": false,
"output_dir": "mocodo_notebook",
"pdf": false,
"plateau": 30,
"png": false,
"population_size": 1000,
"print_params": false,
"relations": [
"html"
],
"replace": false,
"restore": false,
"reuse_geo": false,
"sample_size": 7,
"scale": 1,
"seed": null,
"shapes": "copperplate",
"strengthen_card": "_1,1_",
"timeout": null,
"title": "Sans titre",
"verbose": false
}
"""
try:
json.loads(params)
except:
raise RuntimeError("Invalid JSON. Check your syntax on https://jsonlint.com.")
pathlib.Path("mocodo_notebook/params.json").write_text(params.strip(), encoding="utf8");
Modifiez la variable params
à votre gré en respectant la syntaxe JSON (attention en particulier au dernier couple clé-valeur, qui n'est pas terminé par une virgule). Exécutez la cellule pour créer un fichier de nom et emplacement adéquats (notez que la valeur de --print_params
a été passée à false
pour vous éviter de le faire à la main).
%%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
La syntaxe ne devrait pas poser problème :
À noter :
%%mocodo
... ne fait pas partie de la description. Dans ce document, elle permet de faire appel à une « commande magique », qui lance Mocodo sur les lignes qui la suivent. Sauf sous Jupyter Notebook, vous pouvez l'omettre dans votre texte d'entrée.
De façon générale, la ou les premières lignes d'un MCD qui commencent par le symbole de pourcentage (%
) sont ignorées. Cela permet de placer en en-tête un commentaire qui pourra être préservé lors des éventuels réarrangements ultérieurs.utf8
, il se rabattra sur le codec d'Europe de l'Ouest associé historiquement à votre plateforme: iso-8859-15
pour Windows et Linux, mac-roman
pour macOS. Si les accents n'apparaissent pas correctement, vous aurez encore trois solutions:--encodings
;params.json
la liste des encodages pris en charge.Lorsque l'une des cardinalités maximales d'une association binaire est 1 (ou à défaut 0), on désigne parfois cette association sous le nom de dépendance fonctionnelle. Certains auteurs la figurent par un cercle portant le symbole DF : cela leur évite de se creuser la tête pour trouver un nom à une association qui disparaîtra corps et bien au moment du passage au relationnel. Enfin, une flèche peut indiquer le sens de la dépendance :
%%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
Si on a plusieurs dépendances fonctionnelles à représenter, on devra suffixer le DF par un chiffre de 0 à 9 (cf. cet exemple).
Elles sont quelquefois appelées associations circulaires ou unaires, et dans tous les cas associent un type d'entité à lui-même.
%%mocodo
HOMME: Num. SS, Nom, Prénom
ENGENDRER, 0N HOMME, 11 HOMME
L'ordre et la séparation des lignes de la description permet de spécifier à coût zéro un plongement grossier, mais qui s'avère en général suffisant:
%%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 boîtes sont placées aux intersections d'une grille invisible assurant que leurs centres soient alignés aussi bien horizontalement que verticalement. C'est ce qui en général est le plus satisfaisant esthétiquement, mais d'autres retouches peuvent être opérées manuellement dans le fichier de sortie.
Le plongement fait l'objet d'une « compression » horizontale et verticale. Par exemple, ci-dessus, il y a un espace horizontal négatif entre le bord droit de l'entité de gauche et le bord gauche de l'entité de droite.
Préfixer d'un tiret bas (_
) les second, troisième, etc. attributs pour les inclure à l'identifiant.
%%mocodo
GRATTE-CIEL: latitude, _longitude, nom, hauteur, année de construction
Suffixer 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
La position de la flèche sur la patte peut être réglée individuellement dans l'objet ratio
du fichier de géométrie généré (par défaut, sandbox_geo.json
) ou sous l'onglet Retouches de la version en ligne. La valeur correspondante peut varier de 0.0
(flèche cachée sous la boîte d'origine) à 1.0
(par défaut, pointe de la flèche au contact du bord de la boîte de destination, compte non tenu de l'arrondi s'il s'agit d'une association).
Plusieurs styles prédéfinis sont distribués avec l'application. Un style se définit comme la combinaison d'une palette de couleurs (répertoire colors
) avec un dictionnaire de polices et de dimensions (répertoire shapes
). Un changement d'échelle d'un facteur multiplicatif positif peut être précisé avec l'argument --scale
.
Vous pouvez bien sûr créer vos propres styles en vous inspirant des fichiers fournis. Si vous êtes particulièrement content d'un style, soumettez-le pour inclusion dans une prochaine distribution.
Nouveauté de la version 3.0. Une approximation de la largeur des caractères des différentes polices a été pré-calculée sous macOS. Il est possible qu'elle soit inexacte, en particulier sous Windows ou Linux. Dans ce cas, en particulier, les traits de soulignement n'atteindront pas ou excéderont la largeur des libellés soulignés. Vous pouvez contourner le problème en appliquant un facteur multiplicatif avec l'argument --adjust_width
).
Chaque attribut peut être assorti de notes entre crochets. Ignorées au niveau du tracé du MCD, elles sont interprétées comme des types de données lors de la génération d'un code-source SQL.
Par défaut, les cardinalités sont séparées par une virgule.
Nouveauté de la version 2.1. On peut maintenant opter pour un format quelconque:
%%mocodo --card_format={min_card}/{max_card}
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
Certaines fautes de frappe fréquentes (inversion des cardinalités minimale et maximale, lettre « O » au lieu du chiffre « 0 ») sont silencieusement rectifiées, d'autres non (lettres « l » ou « I ») :
formes erronées | forme rectifiée |
---|---|
O1 , o1 , 10 , 1O , 1o |
01 |
ON , oN , NO , No , N0 |
0N |
On , on , no , nO , n0 |
0n |
N1 |
1N |
n1 |
1n |
Les cardinalités (N,N), qui selon une certaine école dénotent une cardinalité minimale supérieure à 1, sont laissées telles quelles.
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, oN CLIENT, 11 COMMANDE
COMMANDE: Num commande, Date, Montant
INCLURE, lN COMMANDE, ON PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Il est possible d'activer l'encerclement d'un autre sigle que DF. C'est ce sigle qui devra alors apparaître en entrée, par exemple:
%%mocodo --df=CIF
CLIENT: Réf. client, Nom, Prénom, Adresse
CIF, 0N CLIENT, 11 COMMANDE
COMMANDE: Num commande, Date, Montant
INCLURE, 1N COMMANDE, 0N PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Comme le cercle est alors un peu plus grand, on peut vouloir régler (a priori une fois pour toutes) le ratio défini dans l'objet shapes
du fichier appelé par défaut sandbox_geo.json
):
"df_text_height_ratio" : 1.00,
Normalement on doit choisir des noms différents pour toutes les boîtes (entités et associations) du MCD, à l'exception des associations de dépendance fonctionnelle figurées par un sigle. On a vu que dans ce cas, il suffisait d'ajouter à leur nom un chiffre de 0 à 9 : celui-ci n'apparaîtra pas en sortie.
Cette possibilité vaut pour n'importe quelle boîte, y compris les triangles dénotant l'héritage (p. ex. /1\
ou /XT2\
).
Seul le dernier chiffre est concerné. Cela limite à 10 le nombre d'entités ou associations homonymes, mais peut être utile si vous avez besoin, pour une raison ou une autre, qu'un suffixe numérique apparaisse dans le nom d'une boîte. Il suffit alors d'ajouter encore un chiffre à celui-ci.
%%mocodo
Agent 0070: bar
DF42, 11 Agent 0070, 1N Agent1
Agent1: bar
La création de boîtes homonymes servira typiquement à « distribuer » une entité DATE réduite à son identifiant date, mais associée à de nombreuses entités qui n'ont rien à voir entre elles. Sachant qu'une telle entité est amenée à disparaître lors du passage au relationnel, il n'y a aucun inconvénient à en créer plusieurs, et cela peut avoir l'avantage de faciliter (ou même de rendre possible) l'obtention d'une bonne mise en page.
Par exemple, la mise en page du MCD suivant est indûment complexifiée par le haut degré de l'entité DATE.
%%mocodo
:
Rhoncus: dolor a, bibendum, euismod, consectetuer, leo
Porttitor, 1N Rhoncus, 1N Curabitur
:
:
Ultricies, 11 Rhoncus, 0N Egestas
Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE
Curabitur: blandit, suscipit
Mollis, 0N Curabitur, 0N Curabitur
:
:
Egestas: vivamus, semper, aliquam
Pharetra, 0N Curabitur, 0N DATE, 0N Vitae justo: massa
Vitae justo: lobortis, purus
adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE
:
:
DATE: date
:
:
Ajouter une autre entité DATE (sous le nom de DATE2) permettra à Mocodo de calculer une mise en page à la fois plus agréable à l'œil et plus compacte (à savoir, $4\times3$ au lieu de $5\times4$). La sémantique est inchangée.
%%mocodo
Egestas: vivamus, semper, aliquam
DATE: date
Pharetra, 0N Curabitur, 0N DATE, 0N Vitae justo: massa
Vitae justo: lobortis, purus
Ultricies, 11 Rhoncus, 0N Egestas
Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE
Curabitur: blandit, suscipit
adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE2
Rhoncus: dolor a, bibendum, euismod, consectetuer, leo
Porttitor, 1N Rhoncus, 1N Curabitur
Mollis, 0N Curabitur, 0N Curabitur
DATE2: date
Préfixer d'un tiret bas (_
) une cardinalité (1,1) pour indiquer que l'entité distinguée est faible. Dans le diagramme, les identifiants (ou discriminants) d'une telle entité seront soulignés en pointillés, tandis que le (1,1) sera souligné d'un trait plein.
%%mocodo
ŒUVRE: Cote œuvre, Titre, Date parution
DF, 1N ŒUVRE, _11 EXEMPLAIRE
EXEMPLAIRE: Num. exemplaire, État du livre, Date d'achat
Nouveauté de la version 2.1. Traditionnellement, l'identification relative est dénotée par des parenthèses autour des cardinalités. Cette notation (ou toute autre) peut maintenant être obtenue avec l'option --strenghten_card
:
%%mocodo --strengthen_card (R)1,1
ŒUVRE: Cote œuvre, Titre, Date parution
DF, 1N ŒUVRE, _11 EXEMPLAIRE
EXEMPLAIRE: Num. exemplaire, État du livre, Date d'achat
Une association ne peut renforcer plus d'une entité faible. Ainsi, une erreur se produit si l'on remplace le 1N
par _11
:
%%mocodo
ŒUVRE: Cote œuvre, Titre, Date parution
DF, _11 ŒUVRE, _11 EXEMPLAIRE
EXEMPLAIRE: Num. exemplaire, État du livre, Date d'achat
Nouveauté de la version 3.2. Certains utilisateurs avancés de Mocodo ont besoin d'exprimer au niveau conceptuel les contraintes sur associations introduites par Merise 2. Jusqu'ici, ils devaient utiliser un éditeur graphique pour ajouter « à la main » les éléments correspondants. Ils peuvent dorénavant le faire sous Mocodo. Attention, la prise en charge de ces extensions est purement visuelle : le passage au niveau relationnel et/ou physique les ignorera.
D'un point de vue purement visuel, donc, une telle contrainte est figurée par un petit rond portant jusqu'à trois lettres:
%%mocodo
(): 20, 45
(Z): 30, 30
(ZZ): 50, 15
(ZZZ): 80, 10
:
:
:
:
Lorem ipsum: lorem, ipsum
La syntaxe nécessite quelques explications.
De la même manière qu'avec les cardinalités, on peut insérer un court texte entre crochets qui apparaîtra au survol de la contrainte.
%%mocodo
() [adipiscing elit]: 20, 45
(Z) [sed do eiusmod]: 30, 30
(ZZ) [tempor incididunt] : 50, 15
(ZZZ) [ut labore]: 80, 10
:
:
:
:
Consectetur: lorem ipsum, dolor sit amet
Les contraintes sont normalement liées par des traits pleins (--
) ou pointillés (..
) à un certain nombre de boîtes (entités ou associations). Une flèche (>
ou <
) peut être ajoutée ou substituée à l'une et/ou l'autre des extrémités d'un trait.
%%mocodo
(A) --Lorem, ..Ipsum, -Dolor: 30, 10
(B) ->Dolor, <-->Sit, -->Amet: 69, 10
:
:
Lorem: lorem, ipsum
Ipsum, XX Lorem, XX Dolor
Dolor: dolor, sit
Sit, XX Dolor, XX Amet
Amet: consectetur, adipiscing
Voici un exemple plus réaliste, adapté de la Fig. 7.37 de Merise, deuxième génération (Dominique Nanci et Bernard Espinasse, 4e éd., 2001) :
%%mocodo
:::::
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
Notez que les ratios de positionnement sont manquants. Dans ce cas, le moteur de plongement fait coïncider le centre de chaque contrainte avec le barycentre des boîtes qu'elle met en jeu. Le positionnement ainsi défini a plus de chances de rester correct si le MCD évolue.
On peut tirer parti de ce mécanisme en intégrant (fictivement) d'autres boîtes à la définition de la contrainte, ou même en en répétant certaines. Dans ces deux cas, bien entendu, le trait devra être rendu invisible (il suffit de l'omettre). Par exemple, intégrer l'entité Commande et répéter l'association Stocker permet de réduire la largeur du MCD sans compromettre sa lisibilité. Ci-dessous, on a en outre indenté la définition de la contrainte pour la placer sur un second calque :
%%mocodo
:::
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, Stocker
Redisons-le : à l'heure actuelle (19h05), seul l'aspect graphique des contraintes est implanté. L'éventuel aspect relationnel de certains types de contrainte est déjà pris en charge par Mocodo, mais d'une autre manière. C'est ce que nous allons voir dans les deux sections suivantes.
Le MCD ci-dessous a (au moins) un défaut :
%%mocodo --mld
Date: Date
Réserver, 1N Client, 1N Chambre, 0N Date: Durée
Chambre: Numéro, Prix
Client: Id. client
Il n'empêche pas les « sur-réservations » : deux clients peuvent réserver la même chambre pour la même nuit. En effet, deux réservations sont complètement identifiées avec les mêmes date et numéro de chambre dès lors que le nom du client est différent.
La notion d'agrégation vient à la rescousse. Elle permet d'agréger les entités DATE et CHAMBRE, ainsi que l'association RÉSERVER, en une « pseudo-entité » qui sera alors considérée comme associée à l'entité CLIENT.
Syntaxiquement, il suffit de préfixer la cardinalité de CLIENT d'une barre oblique (avant la version 3, cela se faisait en préfixant le nom de l'entité et non sa cardinalité) :
%%mocodo --mld
Date: Date
Réserver, /1N Client, 1N Chambre, 0N Date: Durée
Chambre: Numéro, Prix
Client: Id. client
Cette visualisation elle-même est une nouveauté de la version 3. Notez que la représentation traditionnelle demanderait à insérer une association DF entre CLIENT et RÉSERVER, ce qui donnerait ceci :
display.SVG("traditional_cluster.svg")
... mais permettre l'association d'une entité et d'une association demanderait à apporter au code de Mocodo des changements conséquents, pour un bénéfice qui ne nous saute pas forcément aux yeux.
Cette situation s'exprime également à l'aide de la notion de contrainte sur associations, et plus précisément de contrainte d'intégrité fonctionnelle. À partir de la version 3.2, on pourra donc choisir d'écrire :
%%mocodo --mld
Date: Date
Réserver, /1N Client, 1N Chambre, 0N Date: Durée
Chambre: Numéro, Prix
:
Client: Id. client
(CIF) [Même date, même chambre => un seul client] --Chambre, --Date, ->Client, ..Réserver: 20, 75
Lorsque Mocodo rencontre une définition de CIF dans le texte-source, il désactive par politesse sa visualisation des pseudo-entités. Mais c'est toujours le /1N Client
qui permet d'obtenir le schéma relationnel attendu : pensez à le mettre.
Notez qu'on peut se passer de la notion d'agrégation dès lors que l'on a celle d'entité faible. Le même MCD pourrait se représenter ainsi :
%%mocodo
Date: Date
DF1, 0N Date, _11 Réserver
Réserver: _Durée
DF2, 0N Chambre, _11 Réserver
Chambre: Numéro, Prix
DF3, 11 Réserver, 1N Client
Client: Id. client
Sous Mocodo, l'agrégation est traitée comme un cas particulier de ce que nous appelons une réduction de clé primaire. Le mécanisme est décrit ici).
Rien ne nous empêche par exemple de créer un agrégat réduit à une seule entité :
%%mocodo
LACUS: blandit, elit
LIGULA, 0N LACUS, /1N EROS: metus
EROS: congue, nibh, tincidunt
Pour en revenir à la représentation graphique :
%%mocodo
EROS: congue, nibh, tincidunt
LIGULA, 0N LACUS, /1N EROS, 0N TELLUS: metus
TELLUS: integer, odio
LACUS: blandit, elit
Si ces conditions ne sont pas réunies, pour des raisons de simplicité du code et de clarté du diagramme, l'enveloppe n'est pas affichée. Cependant, les pointillés de la ou des pattes concernées subsistent et le reste des traitements est inchangé.
%%mocodo
TELLUS: integer, odio
CONSEQUAT: fermentum, dederit
LIGULA, 0N LACUS, /1N EROS, 0N TELLUS, 0N CONSEQUAT: metus
LACUS: blandit, elit
EROS: congue, nibh, tincidunt
Normalement, les associations DF disparaissent lors du passage en relationnel. Il est cependant possible de forcer la création d'une table éponyme. Cela se fait en mettant entre crochets droits le nom de l'association (avant la version 3, on préfixait d'une barre oblique l'une au moins des entités non distinguées par un (0,1)).
Au niveau visualisation, un rectangle en pointillés apparaît autour de l'association, indiquant que celle-ci va devenir une table.
%%mocodo
LACUS: blandit, elit
[LIGULA], 01 LACUS, 1N EROS: metus
EROS: congue, nibh, tincidunt
La motivation et les détails sont discutés dans la section Passage au relationnel / Conversion forcée d'une association DF en table.
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.
La syntaxe Mocodo est la suivante :
/\ Mère <- Fille_1, Fille_2, ... : type
Où :
/\
, soit /X\
, soit /T\
, soit /XT\
(éventuellement suffixé par un chiffre de 0 à 9, p. ex. /1\
ou /XT2\
) ;<=
, soit <-
, soit ->
, soit =>
. Reportez-vous à cette section ;Voici un exemple :
%%mocodo
Personne: num SS, nom, prénom
/XT\ Personne <- Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Selon les symboles inscrits dans le triangle, le MCD précédent s'interprétera ainsi :
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 |
Ces contraintes ne sont pas transposables au niveau relationnel, mais pourront être réinjectées au niveau physique (même si Mocodo ne le fait pas actuellement).
Le type de flèche spécifiant le mécanisme de passage au modèle relationnel (<=
, <-
, ->
ou =>
) fait par défaut l'objet d'une visualisation dès le modèle conceptuel : la ou les pattes vers les entités de destination des attributs migrants sont orientées vers celles-ci ; et la ou les autres pattes sont doublées (pour <=
et =>
) ou non (pour <-
et ->
).
%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne => Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Cette visualisation n'est pas conventionnelle : par défaut, on se borne à ajouter une flèche dirigée vers l'entité-mère. Pour désactiver l'embellissement opéré par Mocodo, sans pour autant changer le mécanisme de passage au relationnel, répétez simplement le deuxième caractère de la flèche : <==
, <--
, ->>
ou =>>
.
%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne =>> Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Si vous n'êtes pas enseignant de bases de données, vous pouvez passer directement à la section suivante.
Les débutants ont souvent des doutes sur la sémantique de telle ou telle cardinalité. Cette information peut désormais être incluse dans le texte-source, en annotant les pattes correspondantes, pour apparaître à la demande lors du rendu (utile pour créer des exercices à faire en TD ou en autonomie).
Survolez les cardinalités du MCD ci-dessous pour faire apparaître leur description.
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, 0N [Un client peut passer un nombre quelconque de commandes.] CLIENT, 11 [Toute commande est passée par un en un seul client.] COMMANDE
COMMANDE: Num commande, Date, Montant
INCLURE, 1N [Une commande peut inclure plusieurs produits distincts, et en inclut au moins un.] COMMANDE, 0N [Certains produits ne sont jamais commandés, d'autres le sont plusieurs fois.] PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Les notes s'insèrent entre cardinalités et nom de l'entité. Elles sont délimitées par des crochets droits.
Avec l'option --disambiguation=notes
(par défaut), elles sont également exploitables lors du passage au relationnel pour préciser la sémantique d'une clé étrangère.
L'affichage est désactivé avec l'option --hide_notes
.
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 --shapes copperplate
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.
Limitations actuelles.
Nouveauté de la version 3.1.1. Dans un cas très rare, à savoir lorsque plusieurs SVG interactifs générés à partir du même texte-source coexistent sur une même page web (ou dans le même notebook), 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 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 pas XX
(ci-dessous à gauche) ou (nouveauté de la version 3.2) en les préfixant d'un -
(ci-dessous à droite).
%%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
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
Enfin, 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 --colors=blank
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
Attention, n'utilisez pas cette méthode si vous souhaitez diffuser l'exercice sous forme électronique: l'information textuelle est toujours présente, susceptible d'être sélectionnée et collée ailleurs pour être lue. Vous pouvez bien sûr empêcher cette possibilité en convertissant la figure dans un format bitmap (comme PNG); mais le plus simple est de combiner les deux méthodes précédentes:
%%mocodo
CLIENT: , ,,
PASSER, XX CLIENT, XX COMMANDE
COMMANDE: , ,
INCLURE, XX COMMANDE, XX PRODUIT:
PRODUIT: , ,
L'obfuscation d'un MCD consiste à vider celui-ci de sa sémantique de surface, en substituant des chaînes aléatoires à tous les libellés. Le résultat sera par exemple utilisé pour montrer que les principales règles de passage du schéma conceptuel au schéma relationnel peuvent être appliquées « bêtement », c'est-à-dire sans comprendre le fonctionnement de l'organisme modélisé.
Ainsi, dans l'exemple ci-dessous, les libellés du MCD CLIENT-COMMANDE-PRODUIT sont remplacés par des mots tirés au hasard:
%%mocodo --obfuscate --seed=1
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
Nouveauté de la version 2.0.20. Pour remplacer le texte de la cellule par le résultat de son évaluation, ajoutez l'option --replace
.
En argument, vous pouvez ajouter le chemin d'un fichier texte UTF-8 quelconque où puiser les mots de substitution. Par exemple, le texte du README
de ce projet:
%%mocodo --obfuscate=../README.md --seed=42 --no_mcd
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 essaie d'abord de trouver ce fichier à l'endroit indiqué. En cas d'échec, il le cherche (avec extension .txt
facultative) parmi les textes distribués avec le logiciel, à savoir:
"lorem_ipsum.txt"
: le faux-texte le plus courant."disparition.txt"
: le lexique du célèbre roman lipogrammatique de Georges Perec."four_letter_words.txt"
: une sélection (SFW) de mots anglais de quatre lettres.En cas de nouvel échec, il se rabat sur "lorem_ipsum.txt"
.
Notez enfin que l'algorithme s'assure que la distance de Damerau-Levenshtein entre deux libellés de substitution quelconques est d'au moins 3 (valeur par défaut du paramètre obfuscation_min_distance
). 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 retrouver son intention première.
Nouveautés de la version 3.
--obfuscation_max_length
est supprimée ; inversement, la taille minimale d'un mot de substitution est fixée (en dur) à 3.--seed
fonctionne quelle que soit la version de Python.La technique de duplication vue plus haut 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
:
DF1, 1N ŒUVRE1, _11 EXEMPLAIRE1
::
DF2, XX ŒUVRE2, XX EXEMPLAIRE2
DF3, XX ŒUVRE2, XX EXEMPLAIRE3
DF4, 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.
Nouveauté de la version 3.2. Pour préserver la sémantique des cardinalités sans les afficher, il est maintenant possible de les préfixer d'un -
(« moins »). Le résultat de la conversion en relationnel peut alors être interprété comme l'ensemble des lignes des différentes tables.
%%mocodo --mld
ŒUVRE: 612.NAT.34, J'apprends à lire à mes souris blanches, mai 1975
DF1, -1N ŒUVRE, -_11 EXEMPLAIRE1
DF2, -1N ŒUVRE, -_11 EXEMPLAIRE2
DF3, -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 ne comprennent pas toujours du premier coup que l'ordre des lignes du texte-source correspond à celui des boîtes du MCD affiché ; ou qu'il faut sauter une ligne chaque fois que l'on veut une nouvelle rangée de boîtes. Ces malheureux se retrouvent donc plus souvent qu'à leur tour avec des chevauchements pas forcément faciles à voir :
%%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é
Ci-dessus, par exemple, l'association INCLURE, qui devrait se trouver entre CLIENT et COMMANDE, est déportée de telle sorte que ses pattes chevauchent COMMANDE, PRODUIT et PASSER, — ce qui ne se voit pas vraiment puisque les entités et associations sont tracées après les pattes.
Nouveauté de la version 3.0. Mocodo peut lever une erreur dans une telle situation. L'option correspondante, --detect_overlaps
est par défaut activée sous Mocodo online, et désactivée en ligne de commande.
Si cela se produit, vous pouvez :
--arrange
en ligne de commande).Remarques.
%%mocodo
CLIENT: Réf. client, Nom, Prénom, Adresse
::
:
COMMANDE: Num commande, Date, Montant
:
::
PASSER, 0N CLIENT, 11 COMMANDE
Le tracé réalisé par Mocodo pour des MCD de plusieurs rangées laisse parfois à désirer :
%%mocodo
Quis, 01 Risus, 1N Ipsum a
Ipsum a: semper, massa
Odio, 1N Ipsum a, 0N Posuere: suscipit
Ac, 01 Risus, 0N Risus
Risus: euismod, semper, dederit, ribandum
Diam leo, 1N Risus, 0N Posuere
Posuere: semper, massa
Pretium, 0N Posuere, 0N Posuere
Curae, 0N Risus, 0N Tellus: pede
METUS, 11 Tellus, 0N Posuere
Ultrices: libero
Lorem, 0N Ultrices, 0N Tellus, 0N Risus: lacus, feugiat
Tellus: domus, tempero
On voit que, par défaut, Mocodo centre les rangées qui contiennent moins de boîtes que les autres. Cela donne un bon résultat pour la première rangée, mais pas pour la troisième.
L'utilisateur peut cependant 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. Ainsi, il va préciser que l'association Curae doit commencer sur la troisième colonne en insérant des lignes réduites au caractère deux-points, et en profiter pour insérer un espace entre Lorem et Tellus :
%%mocodo
Quis, 01 Risus, 1N Ipsum a
Ipsum a: semper, massa
Odio, 1N Ipsum a, 0N Posuere: suscipit
Ac, 01 Risus, 0N Risus
Risus: euismod, semper, dederit, ribandum
Diam leo, 1N Risus, 0N Posuere
Posuere: semper, massa
Pretium, 0N Posuere, 0N Posuere
:
:
Curae, 0N Risus, 0N Tellus: pede
METUS, 11 Tellus, 0N Posuere
:
Ultrices: libero
Lorem, 0N Ultrices, 0N Tellus, 0N Risus: lacus, feugiat
:
Tellus: domus, tempero
Il est possible de « compresser » les suites de deux-points en supprimant les retours-chariots, autrement dit, de remplacer $n$ lignes réduites à deux-points par une ligne réduite à une séquence de $n$ deux-points. Ce raccourci est illustré dans le prochain exemple.
Nouveauté de la version 2.2. On cherche en général à faire tenir le MCD dans la plus petite grille possible, tout en maintenant un rapport « équilibré » entre hauteur et largeur. Par exemple, un MCD de 13 boîtes (entités ou associations) peut tenir dans les grilles:
Les deux premières grilles étant non équilibrées, on retiendra la plus petite des suivantes, de dimensions $5\times3$.
La table ci-dessous énumère les dimensions des grilles minimales d'équilibre supérieur à 0,5 pour tous les MCD comportant moins de 100 boîtes. On peut y vérifier par exemple que le MCD de taille 13 se trouve effectivement aux coordonnées (5, 3).
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 2 | 3 | ||||||||||
2 | 4 | 5, 6 | |||||||||||
3 | 7, 8, 9 | 10, 11, 12 | 13, 14, 15 | ||||||||||
4 | 16 | 17, 18, 19, 20 | 21, 22, 23, 24 | 26, 27, 28 | |||||||||
5 | 25 | 29, 30 | 31, 32, 33, 34, 35 | 37, 38, 39, 40 | 43, 44, 45 | ||||||||
6 | 36 | 41, 42 | 46, 47, 48 | 50, 51, 52, 53, 54 | 57, 58, 59, 60 | 65, 66 | |||||||
7 | 49 | 55, 56 | 61, 62, 63 | 67, 68, 69, 70 | 73, 74, 75, 76, 77 | 82, 83, 84 | 91 | ||||||
8 | 64 | 71, 72 | 78, 79, 80 | 85, 86, 87, 88 | 92, 93, 94, 95, 96 | ||||||||
9 | 81 | 89, 90 | 97, 98, 99 | ||||||||||
10 | 100 |
Nouveauté de la version 3.0. La contrainte d'équilibre est relaxée pour les MCD à 2 et 3 boîtes, qui sont placées respectivement sur des grilles $2\times1$ et $3\times1$ au lieu de $2\times2$.
Avec l'option --fit
, Mocodo reformate automatiquement le MCD pour le faire entrer dans la grille minimale correspondante:
%%mocodo --fit
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
L'algorithme se contente de supprimer ou d'insérer des sauts de ligne dans le texte-source, sans modifier l'ordre des clauses. On devra donc encore en général opérer sur le résultat un réarrangement automatique (voir plus loin).
%%mocodo --arrange --seed=42
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
::
Si ce réarrangement échoue ou laisse à désirer, il est possible de spécifier chacune des ièmes grilles suivantes avec l'option --fit=i
:
%%mocodo --fit=1
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
%%mocodo --arrange --seed=4
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
:::
Remarques.
--fit
définit une grille trop grande, le réarrangement automatique retombe fréquemment sur une sous-grille de celle-ci.--fit=0
et --arrange=bb
. Dans la plupart des cas, cela permet d'obtenir le meilleur résultat. Mais il peut également arriver que la grille minimale soit trop étroite pour autoriser un plongement planaire. Dans ce cas, cliquez sans alt pour débrayer la première opération.Nouveauté de la version 2.1. Mocodo est capable de détecter certaines configurations de pattes dont les cardinalités présentent un risque élevé de collision. Il procède alors à deux types d'ajustements:
Ces ajustements automatiques résolvent les problèmes les plus courants. Toutefois, étant antérieurs au tracé proprement dit, ils peuvent seulement réduire les risques de collision, et non les prévenir totalement. Ils peuvent même en produire d'autres. Ainsi, autour des entités particulièrement pattues, des collisions qui ne se seraient pas produites par défaut seront parfois observées. L'utilisateur a alors deux possibilités:
--flex
(par défaut, 0.75
) pour réduire la courbure de l'inflexion automatique, en allant jusqu'à 0
pour la désactiver totalement (exemple)).Lors du plongement, Mocodo génère systématiquement un fichier (intitulé par défaut sandbox_geo.json
) répertoriant les positions les plus importantes du dessin. La plupart des autres coordonnées sont calculées relativement à celles-ci.
%%mocodo --shapes trebuchet --colors=brewer+1
Velit, 0N Blandit, 0N Nonummy: sollicitudin
Blandit: consequat, ligula, nibh, consequat
:::
Nonummy: consequat, ligula
Vivamus, 0N Nonummy, 0N Blandit: eleifend, iaculis
Si on ouvre le fichier de géométrie généré, on y retrouvera les principaux paramètres de position:
display.Code("mocodo_notebook/sandbox_geo.json")
width
et height
définit la taille du MCD ;cx
et cy
, les abscisses et ordonnées des centres des boîtes ;shift
, les positions relatives des cardinalités par rapport à leur position par défaut ;ratio
, les positions des flèches éventuelles.Pour rendre le plongement plus compact, nous apportons à ce fichier quelques modifications :
%%file mocodo_notebook/sandbox_geo.json
{
"width": 384,
"height": 155,
"cx": [
[ "Velit", 192 ],
[ "Blandit", 47 ],
[ "Nonummy", 337 ],
[ "Vivamus", 192 ]
],
"cy": [
[ "Velit", 35 ],
[ "Blandit", 73 ],
[ "Nonummy", 73 ],
[ "Vivamus", 111 ]
],
"shift": [
[ "Velit,Blandit,0", -30 ],
[ "Velit,Nonummy,0", -30 ],
[ "Vivamus,Nonummy,0", -30 ],
[ "Vivamus,Blandit,0", -30 ]
],
"ratio": []
}
Il suffit maintenant d'ajouter l'option --reuse_geo
pour appliquer ces modifications :
%%mocodo --shapes trebuchet --colors=brewer+1 --reuse_geo
Velit, 0N Blandit, 0N Nonummy: sollicitudin
Blandit: consequat, ligula, nibh, consequat
:::
Nonummy: consequat, ligula
Vivamus, 0N Nonummy, 0N Blandit: eleifend, iaculis
Tous les navigateurs modernes prennent en charge la visualisation des SVG. Pour aller au-delà, il faudra faire appel à un logiciel de dessin vectoriel dédié, comme Inkscape (libre) ou Adobe Illustrator, Freehand, CorelDRAW, etc. Les éléments du fichier SVG produit pourront alors être repositionnés à la souris. Certains sont groupés pour permettre leur déplacement en bloc. Dans la version actuelle, les liens ne suivent pas ces déplacements, ce qui peut obliger à des manipulations supplémentaires.
Mocodo permet de calculer facilement le symétrique d'un MCD, par exemple celui donné ci-dessous:
%%mocodo
Assistas, 01 Hci poilu, 0N Hci poilu
Hci poilu: graffiti, champignon, troussa, graffiti
Rayonnait, 0N Hci poilu, 0N Lappa: monobloc
Brisa: souffrait
Pillards, 0N Brisa, 0N Lappa, 0N Hci poilu: disions, lascar
Lappa: graffiti, champignon
Puni, 11 Lappa, 0N Lappa
Nouveauté de la version 2.0.20. Pour remplacer le texte de la cellule par le résultat de son évaluation, ajoutez l'option --replace
.
%%mocodo --flip=v
Assistas, 01 Hci poilu, 0N Hci poilu
Hci poilu: graffiti, champignon, troussa, graffiti
Rayonnait, 0N Hci poilu, 0N Lappa: monobloc
Brisa: souffrait
Pillards, 0N Brisa, 0N Lappa, 0N Hci poilu: disions, lascar
Lappa: graffiti, champignon
Puni, 11 Lappa, 0N Lappa
%%mocodo --flip=h
Assistas, 01 Hci poilu, 0N Hci poilu
Hci poilu: graffiti, champignon, troussa, graffiti
Rayonnait, 0N Hci poilu, 0N Lappa: monobloc
Brisa: souffrait
Pillards, 0N Brisa, 0N Lappa, 0N Hci poilu: disions, lascar
Lappa: graffiti, champignon
Puni, 11 Lappa, 0N Lappa
%%mocodo --flip=d
Assistas, 01 Hci poilu, 0N Hci poilu
Hci poilu: graffiti, champignon, troussa, graffiti
Rayonnait, 0N Hci poilu, 0N Lappa: monobloc
Brisa: souffrait
Pillards, 0N Brisa, 0N Lappa, 0N Hci poilu: disions, lascar
Lappa: graffiti, champignon
Puni, 11 Lappa, 0N Lappa
Pour une symétrie selon l'anti-diagonale, appliquer successivement les trois symétries précédentes dans n'importe quel ordre.
La transposition peut être utilisée pour réaliser plus facilement certaines opérations d'édition en colonne, en particulier sous Mocodo online. Par exemple, supposons que l'on souhaite décaler vers le haut la dernière colonne du MCD ci-dessous:
%%mocodo --flex=0
AMET, 11> LOREM, 01 CONSECTETUER: adipiscing
CONSECTETUER: elit, sed
TORTOR, 0N RISUS, 11 DIGNISSIM, 1N CONSECTETUER: nec
DF, 11 RISUS, 0N RISUS
LOREM: ipsum, dolor, sit
SOLLICITUDIN, 0N SUSPENDISSE, 0N CONSECTETUER, 0N LOREM: lectus
DIGNISSIM: ligula, massa, varius
RISUS: ultricies, _cras, elementum
DF1, 11 LOREM, 1N SUSPENDISSE
SUSPENDISSE: diam
MAECENAS, 1N DIGNISSIM, 1N DIGNISSIM
SEMPER, 0N RISUS, 1N DIGNISSIM
On commence par transposer:
%%mocodo --no_mcd --flip=d
AMET, 11> LOREM, 01 CONSECTETUER: adipiscing
CONSECTETUER: elit, sed
TORTOR, 0N RISUS, 11 DIGNISSIM, 1N CONSECTETUER: nec
DF, 11 RISUS, 0N RISUS
LOREM: ipsum, dolor, sit
SOLLICITUDIN, 0N SUSPENDISSE, 0N CONSECTETUER, 0N LOREM: lectus
DIGNISSIM: ligula, massa, varius
RISUS: ultricies, _cras, elementum
DF1, 11 LOREM, 1N SUSPENDISSE
SUSPENDISSE: diam
MAECENAS, 1N DIGNISSIM, 1N DIGNISSIM
SEMPER, 0N RISUS, 1N DIGNISSIM
Il suffit alors d'insérer un deux-points au début de chacune des trois premières rangées, puis de retransposer dans l'autre sens:
%%mocodo --flip=d
:
AMET, 11> LOREM, 01 CONSECTETUER: adipiscing
LOREM: ipsum, dolor, sit
DF1, 11 LOREM, 1N SUSPENDISSE
:
CONSECTETUER: elit, sed
SOLLICITUDIN, 0N SUSPENDISSE, 0N CONSECTETUER, 0N LOREM: lectus
SUSPENDISSE: diam
:
TORTOR, 0N RISUS, 11 DIGNISSIM, 1N CONSECTETUER: nec
DIGNISSIM: ligula, massa, varius
MAECENAS, 1N DIGNISSIM, 1N DIGNISSIM
DF, 11 RISUS, 0N RISUS
RISUS: ultricies, _cras, elementum
SEMPER, 0N RISUS, 1N DIGNISSIM
On peut se convaincre en examinant le nouveau texte d'entrée que le résultat aurait été beaucoup plus pénible à obtenir en procédant directement.
Il est possible de demander à Mocodo de chercher tout seul une « bonne » permutation des boîtes, ce qui à la main deviendrait vite difficile.
Le critère que nous avons retenu pour évaluer la qualité d'une permutation est double:
Deux algorithmes sont fournis :
bb
, pour Branch & Bound), qui ne trouve que des solutions satisfaisant au premier critère;ga
, pour Genetic Algorithm), réservé aux cas où il est impossible d'y satisfaire. L'algorithme va alors chercher des solutions où les liens se coupent seulement le moins possible.Nouveauté de la version 2.0.20. Pour remplacer le texte de la cellule par le résultat de son évaluation, ajoutez l'option --replace
.
Voici à titre d'exemple un résultat trouvé par l'algorithme exact, suivi du MCD correspondant:
%%mocodo --arrange --seed=1
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
Le réarrangement automatique se fera toujours à l'intérieur d'une grille ayant autant de colonnes et de rangées que le texte de départ (ici, $4\times5$). On peut quelquefois essayer de réduire cette grille. Par exemple, le MCD ci-dessus comporte 13 boîtes. Celles-ci pourraient donc théoriquement tenir dans une grille $5\times3=15$. Modifions le texte à la main pour avoir 3 blocs d'au plus 5 lignes, et vérifier qu'un tel réarrangement est possible:
%%mocodo --arrange --seed=4
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
Le réarrangement dit organique consiste à choisir une première boîte au hasard, puis à essayer d'agréger les autres sans se préoccuper de contenir le tout dans une grille prédéterminée.
%%mocodo --arrange --organic --seed=7
Lacus, 01 Blandit, 1N Elit
Elit: ligula, tellus
Metus, 1N Elit, 0N Congue: nibh
Bibendum, 01 Blandit, 0N Blandit
Blandit: consequat, ligula, nibh, consequat
Ipsum, 1N Blandit, 0N Congue
Congue: ligula, tellus
Augue, 0N Congue, 0N Congue
Velit, 0N Blandit, 0N Nonummy: sollicitudin
DF, 11 Nonummy, 0N Congue
Posuere: pede
Vivamus, 0N Posuere, 0N Nonummy, 0N Blandit: eleifend, iaculis
Nonummy: consequat, ligula
Cela donne un autre plongement du MCD sur une grille $4\times5$, ce qui comme on l'a vu n'est pas optimal. Mais on voit aussi qu'il peut être trivialement amélioré. De fait, le réarrangement organique fournit souvent un bon point de départ pour chercher soi-même une permutation plus esthétique ou mettant en évidence certaines propriétés du MCD.
Pour permettre au programme de rendre plus rapidement de bonnes solutions, on a borné arbitrairement le nombre d'appels à la fonction chargée de construire une permutation à partir du placement de la première boîte. De ce fait, l'algorithme n'est plus exact, en ce sens que la meilleure solution peut occasionnellement lui échapper. Si vous soupçonnez que c'est le cas, faites un autre essai, éventuellement en augmentant la borne (par défaut 10000):
mocodo --arrange --call_limit=100000
D'autre part, le réarrangement exact ne fonctionnera jamais sur les MCD:
Rappelons qu'un graphe est dit planaire lorsqu'il en existe au moins un arrangement sans croisement. Le graphe non planaire comportant le plus petit nombre de liens est connu sous le nom de $K_{3,3}$:
%%mocodo
DIGNISSIM: nec sem, nunc, vulputate
IMPERDIET: a praesent, nibh, semper
TINCIDUNT: faucibus, orci, cursus
RHONCUS, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
SODALES, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
QUIS ENIM, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
Son réarrangement par Branch & bound échouera donc nécessairement. Mocodo ne cherche pas à savoir si la non-planarité est intrinsèque au graphe, ou résulte des dimensions de la grille imposée pour le plongement :
%%mocodo --arrange
DIGNISSIM: nec sem, nunc, vulputate
IMPERDIET: a praesent, nibh, semper
TINCIDUNT: faucibus, orci, cursus
RHONCUS, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
SODALES, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
QUIS ENIM, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
Dans tous ces cas, on pourra se rabattre sur l'heuristique. Celle-ci, au lieu d'interdire les croisements, cherche simplement à en minimiser le nombre.
%%mocodo --arrange=ga --seed=42
DIGNISSIM: nec sem, nunc, vulputate
IMPERDIET: a praesent, nibh, semper
TINCIDUNT: faucibus, orci, cursus
RHONCUS, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
SODALES, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
QUIS ENIM, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
L'amélioration ne saute pas forcément aux yeux, mais il n'y a plus que 3 croisements au lieu de 9. Ce plongement constitue en tout cas un bon point de départ pour un réarrangement manuel. Pour arriver à une représentation lisible, il ne reste plus qu'à insérer quelques boîtes invisibles:
%%mocodo
RHONCUS, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
DIGNISSIM: nec sem, nunc, vulputate
:::
IMPERDIET: a praesent, nibh, semper
SODALES, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
:::
QUIS ENIM, 1N DIGNISSIM, 1N IMPERDIET, 1N TINCIDUNT
TINCIDUNT: faucibus, orci, cursus
Mocodo génère systématiquement une sortie au format SVG :
%%mocodo --no_mcd --png --pdf
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
display.SVG("mocodo_notebook/sandbox.svg")
Nouveauté de la version 3.0. Avec les options --pdf
et --png
(ou en cochant les cases correspondantes dans l'onglet Options de la version web), Mocodo convertit désormais ce SVG en PDF et PNG. Le premier format est idéal pour l'inclusion dans des documents destinés à être projetés, diffusés ou imprimés :
display.IFrame("mocodo_notebook/sandbox.pdf", width="100%", height="100%")
Le second est un format bitmap, donc avec une certaine perte de qualité :
display.Image("mocodo_notebook/sandbox.png")
Attention, dans un cas comme dans l'autre, seules les polices de caractères les plus courantes seront composées correctement.
Le passage au relationnel se fait en deux étapes:
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).
Illustrons le premier cas du troisième point sur un MCD comportant des associations triple, double et réflexive dont toutes les cardinalités maximales sont à N.
%%mocodo --mld
LACUS: blandit, elit
LIGULA, 0N LACUS, 1N EROS, 0N TELLUS: metus
EROS: congue, nibh, tincidunt
BIDENDUM, 0N TELLUS, 1N TELLUS: consequat
TELLUS: integer, odio
FAUCIBUS, 1N TELLUS, 0N EROS: ipsum
Notez la désambiguïsation automatique par numérotation du deuxième attribut de BIBENDUM.
Illustrons l'autre cas sur un MCD quasiment identique, à ceci près que certaines cardinalités maximales ont été ramenées à 1. En tant que dépendances fonctionnelles, toutes les associations vont alors disparaître.
%%mocodo --mld
LACUS: blandit, elit
LIGULA, 11 LACUS, 1N EROS, 0N TELLUS: metus
EROS: congue, nibh, tincidunt
BIDENDUM, 0N TELLUS, 11 TELLUS: consequat
TELLUS: integer, odio
FAUCIBUS, 11 TELLUS, 01 EROS: ipsum
Notez les points suivants:
Les deux alternatives mentionnées, plus orthodoxes mais plus lourdes, produisent de toute façon le même schéma relationnel.
Autre point litigieux: dans les dépendances fonctionnelles à double sens ((1,1) des deux côtés), la priorité est donnée à la première des entités énumérées dans l'association. Même chose quand deux (0,1) sont en concurrence.
%%mocodo --mld
TELLUS: integer, odio
FAUCIBUS, 11 TELLUS, 11 EROS: ipsum
EROS: congue, nibh, tincidunt
ORCI: suspendisse, iaculis
MOLLIS, 11 POSUERE, 11 ORCI: lacus
POSUERE: pretium, euismod, porttitor
Les traitements alternatifs (migration dans les deux sens, fusion en une seule table, etc.) ne sont pas pris en charge par Mocodo.
%%mocodo --mld --relations diagram
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
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.
Ce processus apparaît clairement sur le diagramme relationnel généré par la commande précédente:
%mocodo --input mocodo_notebook/sandbox.mld
Les renforcements en cascade sont correctement gérés dans tous les cas, et les renforcements cycliques produisent un message d'erreur.
Mocodo permet de modifier légèrement le nom d'une clé étrangère, de façon à réintroduire la sémantique perdue lors de la disparition de l'association de dépendance fonctionnelle par laquelle elle a migré.
%%mocodo --mld
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
Par exemple, ci-dessus, la conversion en relationnel produit dans la relation ÉTUDIANT des clés étrangères date et date.1 qui ne peuvent être laissées en l'état. Par ailleurs, on peut souhaiter expliciter la raison pour laquelle un numéro d'enseignant apparaît dans la table ÉTUDIANT.
Dans les deux cas, il suffit d'employer le système d'annotation de pattes introduit plus haut:
%%mocodo --mld --no_mcd
Soutenir, 01 Étudiant, 0N [soutenance] Date: note stage
Étudiant: num. étudiant, nom, coordonnées
Date: date
Répondre de, 0N [visite] Date, 11 Étudiant, 0N [responsable] Enseignant
Enseignant: num. enseignant, nom, coordonnées
De façon moins cruciale, la technique s'applique aussi aux autres types d'association:
%%mocodo --mld
CLIENT: Réf. client, Nom, Prénom, Adresse
PASSER, 0N [ayant commandé] CLIENT, 11 [note ignorée] COMMANDE
COMMANDE: Num. commande, Date, Montant
INCLURE, 1N [passée] COMMANDE, 0N [commandé] PRODUIT: Quantité
PRODUIT: Réf. produit, Libellé, Prix unitaire
Pour désactiver cette fonctionnalité (notamment dans le cas où vous annotez chaque cardinalité d'une explication destinée aux novices), passez l'option --disambiguation=numbers_only
.
Le traitement régulier d'une association DF (présence d'une cardinalité (1,1) ou, à défaut, (0,1)) ne la convertit pas en table. On a cependant la possibilité de forcer cette conversion en mettant entre crochets droits le nom de l'association.
Par exemple, supposons une cardinalité (0,1) dans laquelle le 0 est grand devant le 1 en termes de fréquence d'apparition : par défaut, la plupart des occurrences de la clé étrangère ainsi constituée restent vides. Forcer la création d'une table dédiée permettra d'économiser de l'espace de stockage.
%%mocodo --relations html_verbose
LACUS: blandit, elit
[LIGULA], 01 LACUS, 1N EROS: metus
EROS: congue, nibh, tincidunt
display.HTML("mocodo_notebook/sandbox_verbose.html")
Cliquez sur LIGULA ci-dessus pour voir mentionner le fait que la création de la table a été forcée manuellement.
%%mocodo --relations html_verbose
LACUS: blandit, elit
[LIGULA], 11 LACUS, 1N EROS: metus
EROS: congue, nibh, tincidunt
display.HTML("mocodo_notebook/sandbox_verbose.html")
La nouvelle notation fonctionne quelles que soient les cardinalités de l'association. Si cette dernière devait déjà donner lieu à la création d'une table, l'indication est visualisée, mais ignorée lors du passage au relationnel.
%%mocodo --relations html_verbose
LACUS: blandit, elit
[LIGULA], 1N LACUS, 1N EROS: metus
EROS: congue, nibh, tincidunt
display.HTML("mocodo_notebook/sandbox_verbose.html")
Limitation. Cette conversion forcée ne fonctionne pas sur les associations nommées « DF ».
Il arrive qu'un sous-ensemble strict de l'ensemble des identifiants des entités mises en jeu dans une association dont toutes les pattes portent la cardinalité N, suffise à constituer la clé primaire de la table issue de cette association : cela se fait facilement au niveau relationnel en privant de leur caractère identifiant les clés qui n'appartiennent pas à ce sous-ensemble.
%%mocodo --mld
Date: Date
Réserver, /1N Client, 1N Chambre, 0N Date: Durée
Chambre: Numéro, Prix
Client: Id. client
C'est plus ou moins équivalent à la notion traditionnelle d'agrégation ou pseudo-entité. Le traitement se généralise naturellement aux agrégats réduits à une seule entité :
%%mocodo --mld
LACUS: blandit, elit
LIGULA, 0N LACUS, /1N EROS: metus
EROS: congue, nibh, tincidunt
>
) ou l'inverse (<
).-
) ou « maximale » (=
).%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne <- Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Ci-dessus, le passage au relationnel produit une seule table :
NOT NULL
en SQL) fera l'affaire ; s'il n'y a pas totalité, certaines personnes ne sont ni homme, ni femme, et ce booléen est « nullable » ; s'il n'y a pas exclusion, certaines personnes peuvent être à la fois homme et femme, et dans ce cas on peut choisir de coder le type par un entier que l'on interprétera en binaire.%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne <= Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Ci-dessus, on a doublé la flèche pour réaliser une migration « maximale » des entités-filles vers l'entité-mère. Notez le doublement des pattes qui distinguent les entités-filles. Deux nouveaux champs sont apparus : Homme et Femme, censés être de type booléen. Selon le type d'héritage, ils sont ici plus ou moins redondants avec sexe (si c'est /XT\
, sexe est préférable, mais si c'est /\
, sexe peut être supprimé).
%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne -> Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Ci-dessus, on a réalisé une migration « minimale » de la mère vers les filles. Notez l'inversion du sens des flèches sur le schéma conceptuel.
%%mocodo --mld
Personne: num SS, nom, prénom
/XT\ Personne => Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Avec une migration « maximale » vers les entités-filles, les attributs communs sont « déplacés » dans chacune des tables-filles. Aucune table-mère n'est créée.
Cela n'est possible que si l'héritage est total (/T\
ou /XT\
) ; dans le cas contraire, certaines occurrences (celles qui ne sont ni homme, ni femme) seraient perdues. Mocodo lève alors une erreur :
%%mocodo --mld
Personne: num SS, nom, prénom
/X\ Personne => Homme, Femme: sexe
Homme:
:
Femme: nom de jeune fille
Trois des quatre mécanismes de passage au relationnel décrits ci-dessus conduisent à la disparition d'entités. Pour assurer que les jointures restent possibles, il faut alors veiller à « recoller » les références qui transitaient par ces entités. On se donne ci-dessous un MCD où les entités d'un héritage sont associées de façon diverses à des entités externes, et on étudie les tables et le diagramme relationnel produits selon le mécanisme de passage au relationnel demandé.
Aide. Cliquez sur le nom des tables pour lire les explications détaillées. Survolez le libellé des attributs pour afficher leur catégorie attribuée en interne par Mocodo (à des fins de débogage).
Voici un éventail de cas possibles pour le mécanisme de migration <-
vers une entité-mère, avec disparition des entités-filles (le cas <=
, essentiellement identique, n'est pas donné).
%%mocodo --relations diagram html_verbose
SUSCIPIT: orci, lorem
RHONCUS, 1N TRISTIS, 11 SUSCIPIT
:
:
SODALES: convallis, ipsum
VITAE, 11 QUAM, 1N SODALES
QUAM: cras, sed
CONSEQUAT: fermentum, dederit
ELIT, 11 TRISTIS, 1N CONSEQUAT
TRISTIS: magna, vestibulum
/XT\ TRISTIS <- SODALES, NEC, LACUS: type
NEC: pulvinar, audis
MOLLIS, 1N CURABITUR, 11 NEC
CURABITUR: gravida, amor
DIGNISSIM: tellus, terra
ALIQUET, 1N TRISTIS, 1N DIGNISSIM
:
:
LACUS: tempor, fugit
ULTRICES, 1N LIBERO, 1N LACUS
LIBERO: posuere, lacrima