From cbdcc081661d87ed0265b8a7bbb95c1f8b44a49b Mon Sep 17 00:00:00 2001 From: laowantong Date: Mon, 20 Nov 2023 19:55:09 +0100 Subject: [PATCH] close #104 --- .../ullman_cthrsg_mcd_sans_cif_80.png | Bin 0 -> 40172 bytes doc/fr_refman.html | 1362 ++++++++++------- doc/fr_refman.ipynb | 1333 +++++++++------- index.php | 2 +- mocodo/argument_parser.py | 4 + mocodo/association.py | 4 + mocodo/convert/relations.py | 14 +- mocodo/parse_mcd.py | 4 +- mocodo/resources/grammar.lark | 3 +- mocodo/resources/i18n/messages_fr.mo | Bin 28625 -> 28947 bytes mocodo/resources/i18n/messages_fr.po | 8 + .../resources/relation_templates/html-c.yaml | 2 + .../resources/relation_templates/html-ce.yaml | 10 +- mocodo/tools/parser_tools.py | 7 +- mocodo/version_number.py | 2 +- pyproject.toml | 2 +- test/test_association.py | 5 + test/test_parser_tools.py | 1 + test/test_parser_tools_snapshot.txt | 190 ++- test/test_relations.py | 14 +- .../inheritance/mld/inheritance_2_mld.html | 4 +- .../zoo/inheritance/mld/inheritance_2_mld.tex | 4 +- .../zoo/inheritance/mld/inheritance_2_mld.txt | 4 +- web/generate.php | 4 + web/mocodo.js | 5 + 25 files changed, 1784 insertions(+), 1204 deletions(-) create mode 100644 doc/examples/ullman_cthrsg_mcd_sans_cif_80.png diff --git a/doc/examples/ullman_cthrsg_mcd_sans_cif_80.png b/doc/examples/ullman_cthrsg_mcd_sans_cif_80.png new file mode 100644 index 0000000000000000000000000000000000000000..06cca0f89f162e9c1e6b8c324122321201f97ff7 GIT binary patch literal 40172 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

EGwLFJ)-W9Av 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 -

Mocodo 4.1.0 loaded.
+
Mocodo 4.1.1 loaded.
 
@@ -13430,7 +13430,7 @@

Opérations de conversion -

+

@@ -14501,7 +14501,7 @@

-

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). Vous n'aurez plus qu'à remplir les autres attributs :

+

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 :

@@ -14535,59 +14535,59 @@

- - - + + + - - - - - Réserver - Durée + + + + + Réserver + Durée - 1,N - 1,N - 0,N + 1,N + 1,N + 0,N - + - - - - + + + + - Client - id. client - + Date + date + - - - - + + + + - Chambre - id. chambre - + Chambre + id. chambre + - + - - - - + + + + - Date - date - + Client + id. client +

@@ -14622,9 +14622,9 @@

%%mocodo 
 Réserver, 1N Client, 1N Chambre, 0N Date: Durée
 
-Client: id. client, 
-Chambre: id. chambre, 
 Date: date
+Chambre: id. chambre, 
+Client: id. client, 
 
@@ -17750,6 +17750,127 @@

CIF à unicité compl

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 :

+ +
+
+
+
+
+
In [34]:
+
+
+
%%mocodo -t
+Client: Id. client
+Réserver, 1N Client, 0N Chambre: _Date, Durée
+Chambre: Num. chambre, Prix
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + Réserver + Date + + Durée + + 1,N + 0,N + + + + + + + + + + + Client + Id. client + + + + + + + + + + + + Chambre + Num. chambre + + Prix + + +
+ +
+ +
+ +
+ + + +
+
    +
  • Chambre (Num. chambre, Prix)
  • +
  • Réserver (Id. client, _#Num. chambre_, Date, Durée)
  • +
+ +
+ +
+ +
+
+ +
+
+
+
+

L'introduction de cette possibilité, surtout destinée à simplifier le plongement des MCD touffus, est discutée ici.

+
@@ -17839,7 +17960,7 @@

Schéma relationnel
-
In [34]:
+
In [36]:
%mocodo -i ccp -t mld
@@ -17904,7 +18025,7 @@ 

Schéma relationnel
-
In [35]:
+
In [37]:
%mocodo -i ccp -t
@@ -18048,7 +18169,7 @@ 

Diagramme relationnel
-
In [36]:
+
In [38]:
@@ -18108,7 +18229,7 @@

Diagramme relationnel
-
In [37]:
+
In [39]:
-
In [38]:
+
In [40]:
%mocodo -i ccp -t sql
@@ -18398,7 +18519,7 @@ 

Inférence de type
-
In [39]:
+
In [41]:
%%mocodo -t create:types --select rw
@@ -18474,7 +18595,7 @@ 

Inférence de type
-
In [40]:
+
In [42]:
%%mocodo -t create:types=[] --select rw
@@ -18555,7 +18676,7 @@ 

Dialectes de SQL
-
In [41]:
+
In [43]:
%%mocodo -t mysql:b
@@ -18668,7 +18789,7 @@ 

-
In [42]:
+
In [44]:
%mocodo -i ccp -t mld:c
@@ -18733,7 +18854,7 @@ 

-
In [43]:
+
In [45]:
%%mocodo --select all -t mld:c
@@ -18859,7 +18980,7 @@ 

-
In [44]:
+
In [46]:
%%mocodo --select all -t mld:c
@@ -18989,7 +19110,7 @@ 

Ajout

-
In [45]:
+
In [47]:
%%mocodo -t mld:c
@@ -19052,7 +19173,7 @@ 

Ajout

-
In [46]:
+
In [48]:
%%mocodo --select all -t mld:c --shapes trebuchet # changement de police de caractères pour mieux distinguer les 1 des I
@@ -19184,7 +19305,7 @@ 

Ajout

-
In [47]:
+
In [49]:
%%mocodo --select all -t markdown:c sql --shapes trebuchet
@@ -19331,7 +19452,7 @@ 

Ajout

-
In [48]:
+
In [50]:
%%mocodo --shapes trebuchet
@@ -19450,7 +19571,7 @@ 

Ajout

-
In [49]:
+
In [51]:
%%mocodo --shapes trebuchet
@@ -19550,7 +19671,7 @@ 

Gestion des

-
In [50]:
+
In [52]:
%%mocodo -t
@@ -19721,7 +19842,7 @@ 

Gestion des

-
In [51]:
+
In [53]:
%mocodo -i sandbox -t diagram --colors mondrian
@@ -19761,7 +19882,7 @@ 

Gestion des
-

+

@@ -19781,7 +19902,7 @@

Gestion des

-
In [52]:
+
In [54]:
%%mocodo
@@ -19880,7 +20001,7 @@ 

Gestion des

-
In [53]:
+
In [55]:
%mocodo -i sandbox -t
@@ -19937,7 +20058,7 @@ 

Gestion de l'héritage
-
In [54]:
+
In [56]:
%%mocodo --select all -t mld:c
@@ -20078,7 +20199,7 @@ 

Gestion de l'héritage
-
In [55]:
+
In [57]:
%%mocodo --select all -t mld:c
@@ -20215,7 +20336,7 @@ 

Gestion de l'héritage
-
In [56]:
+
In [58]:
%%mocodo --select all -t mld:c sql
@@ -20403,7 +20524,7 @@ 

Gestion de l'héritage
-
In [57]:
+
In [59]:
%%mocodo --select all -t mld:c sql
@@ -20588,7 +20709,7 @@ 

Gestion de l'agrégation
-
In [58]:
+
In [60]:
%%mocodo --select all -t mld:c
@@ -20733,7 +20854,7 @@ 

Gestion de l'agrégation
-
In [59]:
+
In [61]:
%%mocodo --select all -t mld:c
@@ -20902,7 +21023,7 @@ 

Supprimer ou maintenir une

-
In [60]:
+
In [62]:
%%mocodo --select mld mcd -t mld:e
@@ -21121,7 +21242,7 @@ 

Forcer une table p

-
In [61]:
+
In [63]:
%%mocodo --select all -t mld:c
@@ -21247,7 +21368,7 @@ 

Forcer une table p

-
In [62]:
+
In [64]:
%%mocodo --select all -t mld:c --colors mondrian
@@ -21390,7 +21511,7 @@ 

Préc

-
In [63]:
+
In [65]:
%%mocodo -t
@@ -21535,7 +21656,7 @@ 

Préc

-
In [64]:
+
In [66]:
%%mocodo -t mld
@@ -21618,7 +21739,7 @@ 

Préc

-
In [65]:
+
In [67]:
%%mocodo -t
@@ -21737,7 +21858,7 @@ 

Orienter la migrat

-
In [66]:
+
In [68]:
%%mocodo -t mld diagram sql --colors mondrian
@@ -21815,7 +21936,7 @@ 

Orienter la migrat
-

+

@@ -21884,7 +22005,7 @@

Orienter la migrat

-
In [67]:
+
In [69]:
%%mocodo -t mld diagram sql --colors mondrian
@@ -21962,7 +22083,7 @@ 

Orienter la migrat
-

+

@@ -22030,7 +22151,7 @@

Orienter la migrat

-
In [68]:
+
In [70]:
%%mocodo -t mld sql --colors mondrian --select all
@@ -22215,7 +22336,7 @@ 

Graphe des dépendances
-
In [69]:
+
In [71]:
%mocodo -i ccp -t dependencies --defer
@@ -22293,7 +22414,7 @@ 

Diagramme relationnel / DDL BDML
-
In [70]:
+
In [72]:
%mocodo -i ccp -t dbml --title CCP
@@ -22386,7 +22507,7 @@ 

Diagramme relationnel / DDL BDML
-
In [71]:
+
In [73]:
display.SVG("../examples/dbml.svg")
@@ -22402,7 +22523,7 @@ 

Diagramme relationnel / DDL BDML -
Out[71]:
+
Out[73]:
@@ -22433,7 +22554,7 @@

Diagramme relationnel D2
-
In [72]:
+
In [74]:
%mocodo -i ccp -t d2
@@ -22515,7 +22636,7 @@ 

Diagramme relationnel D2
-
In [73]:
+
In [75]:
%mocodo -i ccp -t d2 --defer
@@ -22589,7 +22710,7 @@ 

Diagramme de classes UML
-
In [74]:
+
In [76]:
%mocodo -i ccp --title CCP -t uml:plantuml=- # '-' supprime un préambule par défaut qui ne nous intéresse pas ici
@@ -22675,7 +22796,7 @@ 

Diagramme de classes UML
-
In [75]:
+
In [77]:
%mocodo -i ccp -t uml --defer --colors brewer+5
@@ -22757,7 +22878,7 @@ 

Notation de Chen
-
In [76]:
+
In [78]:
%mocodo -i ccp -t chen --defer --colors ocean
@@ -22809,7 +22930,7 @@ 

Notation de Chen
-
In [77]:
+
In [79]:
%mocodo -i ccp -t chen:attrs --defer --colors ocean
@@ -22876,7 +22997,7 @@ 

Notation crow's foot
-
In [78]:
+
In [80]:
%mocodo -i ccp -t crow --defer --colors brewer+3
@@ -22959,7 +23080,7 @@ 

Dictionnaire des données
-
In [79]:
+
In [81]:
%mocodo -i ccp -t data_dict:tsv
@@ -23000,88 +23121,88 @@ 

Dictionnaire des données - +
- - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + +
 Entité ou associationLibellé de l'attributTypeEntité ou associationLibellé de l'attributType
0ClientAdresseVARCHAR(255)0ClientAdresseVARCHAR(255)
1ClientNomVARCHAR(255)1ClientNomVARCHAR(255)
2ClientPrénomVARCHAR(255)2ClientPrénomVARCHAR(255)
3ClientRéf. clientVARCHAR(8)3ClientRéf. clientVARCHAR(8)
4CommandeDateDATE4CommandeDateDATE
5CommandeMontantDECIMAL(10,2)5CommandeMontantDECIMAL(10,2)
6CommandeNum. commandeVARCHAR(8)6CommandeNum. commandeVARCHAR(8)
7InclureQuantitéINTEGER7InclureQuantitéINTEGER
8ProduitLibelléVARCHAR(50)8ProduitLibelléVARCHAR(50)
9ProduitPrix unitaireDECIMAL(10,2)9ProduitPrix unitaireDECIMAL(10,2)
10ProduitRéf. produitVARCHAR(8)10ProduitRéf. produitVARCHAR(8)
@@ -23115,7 +23236,7 @@

Dictionnaire des données
-
In [80]:
+
In [82]:
%mocodo -i ccp -t data_dict:**box**="Entité ou<br>association",label,`type`=`"Type de données"`
@@ -23244,7 +23365,7 @@ 

Dictionnaire des données
-
In [81]:
+
In [83]:
%mocodo -i ccp -t data_dict:label
@@ -23335,7 +23456,7 @@ 

URL de partage
-
In [82]:
+
In [84]:
%mocodo -i ccp -t share
@@ -23409,7 +23530,7 @@ 

Vue en extension
-
In [83]:
+
In [85]:
%%mocodo
@@ -23614,7 +23735,7 @@ 

Vue en extension
-
In [84]:
+
In [86]:
%%mocodo -t
@@ -23796,7 +23917,7 @@ 

Afficher des explications au survol

-
In [85]:
+
In [87]:
%%mocodo
@@ -23969,7 +24090,7 @@ 

Afficher des explications au survol

-
In [86]:
+
In [88]:
%%mocodo
@@ -24168,7 +24289,7 @@ 

Dévoiler un MCD par étap

-
In [87]:
+
In [89]:
%%mocodo --colors ocean
@@ -24356,7 +24477,7 @@ 

Dévoiler un MCD par étap

-
In [88]:
+
In [90]:
%%mocodo
@@ -24436,7 +24557,7 @@ 

Dévoiler un MCD par étap

-
In [89]:
+
In [91]:
%%mocodo
@@ -24524,7 +24645,7 @@ 

Dévoiler un MCD par étap

-
In [90]:
+
In [92]:
%%mocodo --uid_suffix 1
@@ -24604,7 +24725,7 @@ 

Dévoiler un MCD par étap

-
In [91]:
+
In [93]:
%%mocodo --uid_suffix 2
@@ -24699,7 +24820,7 @@ 

Explications du passage au relat

-
In [92]:
+
In [94]:
%mocodo -i ccp -t markdown:e
@@ -24816,7 +24937,7 @@ 

Supprimer le marquage d'un ident

-
In [93]:
+
In [95]:
%%mocodo
@@ -24944,7 +25065,7 @@ 

Masquer un couple de cardinalit&

-
In [94]:
+
In [96]:
%%mocodo
@@ -25083,7 +25204,7 @@ 

Masquer un attribut
-
In [95]:
+
In [97]:
%%mocodo
@@ -25217,7 +25338,7 @@ 

Ne

-
In [96]:
+
In [98]:
%mocodo -i ccp --colors=blank
@@ -25336,7 +25457,7 @@ 

Ne

-
In [97]:
+
In [99]:
%mocodo -i ccp -t empty # équivalent de "delete:types,notes,attrs,cards"
@@ -25483,7 +25604,7 @@ 

Obfuscation d'un MCD donné
-
In [98]:
+
In [100]:
%mocodo -i ccp --seed=1 --select mcd -t obfuscate  # raccourci pour "obfuscate:labels"
@@ -25602,7 +25723,7 @@ 

Obfuscation d'un MCD donné
-
In [99]:
+
In [101]:
%mocodo -i ccp -t obfuscate:labels=../../README.md --seed=1 --select mcd
@@ -25752,7 +25873,7 @@ 

Croissance stochastique
-
In [100]:
+
In [102]:
%mocodo -i ccp -t grow:n=4 arrange --seed=1 --select mcd
@@ -25990,7 +26111,7 @@ 

Croissance stochastique
-
In [101]:
+
In [103]:
%mocodo --seed=2 --mld -t grow:from_scratch,arity_3=1,_11-*N=1 obfuscate create:roles lower:roles arrange
@@ -26387,7 +26508,7 @@ 

Génération d'un QR code
-
In [102]:
+
In [104]:
%mocodo -i ccp -t share --defer
@@ -26509,7 +26630,7 @@ 

Accès sous terminal o

-
In [103]:
+
In [105]:
path = Path("def_weak-974e.mcd")
@@ -26527,7 +26648,7 @@ 

Accès sous terminal o
-
Out[103]:
+
Out[105]:
@@ -26552,7 +26673,7 @@

Accès sous terminal o

-
In [104]:
+
In [106]:
%mocodo -i def_weak-974e.mcd
@@ -26637,7 +26758,7 @@ 

Accès sous terminal o

-
In [105]:
+
In [107]:
path.is_file()
@@ -26653,7 +26774,7 @@ 

Accès sous terminal o
-
Out[105]:
+
Out[107]:
@@ -26784,7 +26905,7 @@

Arrangement non contraint (

-
In [106]:
+
In [108]:
%mocodo -i ../examples/landing --select mcd --seed=2 -t arrange
@@ -27072,7 +27193,7 @@ 

Arrangement dans la grille courante

-
In [107]:
+
In [109]:
%mocodo -i ../examples/landing --select mcd --seed=2 -t arrange:current
@@ -27352,7 +27473,7 @@ 

Arrangement en privilé

-
In [108]:
+
In [110]:
%mocodo -i ../examples/landing --select mcd --seed=2 -t arrange:wide=8 --scale 0.8
@@ -27845,7 +27966,7 @@ 

Arrangement d

-
In [109]:
+
In [111]:
%mocodo -i ../examples/landing --select mcd --seed=1 -t arrange:balanced=1
@@ -28126,7 +28247,7 @@ 

Limitations de la méthode ex

-
In [110]:
+
In [112]:
%%mocodo
@@ -28271,7 +28392,7 @@ 

Limitations de la méthode ex

-
In [111]:
+
In [113]:
%mocodo -i sandbox --seed=1 -t arrange:balanced
@@ -28311,7 +28432,7 @@ 

Limitations de la méthode ex

-
In [112]:
+
In [114]:
%mocodo -i sandbox --seed=1 -t arrange
@@ -28371,7 +28492,7 @@ 

Méthode

-
In [113]:
+
In [115]:
%mocodo -i sandbox --seed=1 -t arrange:algo=ga
@@ -28546,7 +28667,7 @@ 

Méthode

-
In [114]:
+
In [116]:
%%mocodo
@@ -28705,42 +28826,69 @@ 

Méthode
-

Amélioration du plongement par création d'entités homonymes

+

Amélioration du plongement

-

Une entité liée à de nombreuses associations peut limiter ou même empêcher les possibilités de réarrangement sans croisements. Lorsque cette entité est indépendante et réduite à son identifiant, elle est vouée à disparaître lors du passage au relationnel. Il n'y a donc 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.

-

Le cas typique est celui d'une entité DATE réduite à un identifiant date, qui peut être associée à un grand nombre d'entités n'ayant rien à voir entre elles. Même avec une arité très modeste de 3, elle peut perturber le plongement :

+

Une entité liée à de nombreuses associations peut limiter ou même empêcher les possibilités de réarrangement sans croisements.

+ +
+
+
+
+
+
+

Par duplication d'entités réduites à leur identifiant

+
+
+
+
+
+
+

Lorsque cette entité est indépendante et réduite à son identifiant, elle est vouée à disparaître lors du passage au relationnel. Il n'y a donc 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.

+

Prenons comme exemple un MCD extrait d'une étude de François de Sainte Marie, et présenté comme suit :

+

+

Le graphe sous-jacent étant non planaire, des croisements sont inévitables (ici entre certaines pattes des associations SHR, CT et THR). Cependant, cette non-planarité résulte elle-même de la mise en jeu d'une même entité Période dans quatre associations triples. La monnayer en quatre entités Période numérotées augmente l'ordre du graphe, mais le rend planaire, le tout sans impact sur le schéma relationnel :

-
In [115]:
+
In [117]:
%%mocodo -t
+Étudiant: id. étudiant, nom étudiant
 :
 :
-DATE: date
-Egestas: vivamus, semper, aliquam
+SHR, 0N Période3, 0N Salle, 0N Étudiant
+Période3: heure
+
+:
+CSG, 0N Niveau, 1N Cours, 1N Étudiant
+Niveau: niveau
 :
 
-Adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE
-Vitae justo: lobortis, purus
-Pharetra, 0N Curabitur, 0N DATE, 0N Vitae justo: massa
-Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE
-Ultricies, 11 Rhoncus, 0N Egestas
+CHS, 0N Période2, 0N Cours, 0N Étudiant
+Cours: id. cours, nom cours
+CHR, 0N Période4, 0N Salle, 0N Cours
+Salle: id. salle, nom salle
+
+Période2: heure
+CT, 11 Cours, 1N Professeur
+Période4: heure
+:
+:
 
 :
-Mollis, 0N Curabitur, 0N Curabitur
-Curabitur: blandit, suscipit
-Porttitor, 1N Rhoncus, 1N Curabitur
-Rhoncus: dolor a, bibendum
+Professeur: id. professeur, nom professeur
+:
+THR, 0N Période1, 0N Salle, 0N Professeur
+Période1: heure
 
@@ -28758,174 +28906,228 @@

- - + + - + - - - + + + - - - - - Adipiscing + + + + + SHR - 0,N - 0,N - 0,N + 0,N + 0,N + 0,N - + - - - + + + - - - - - Pharetra - massa + + + + + CSG - 0,N - 0,N - 0,N + 0,N + 1,N + 1,N - + - - - + + + - - - - - Imperdiet + + + + + CHS - 0,N - 0,N - 0,N + 0,N + 0,N + 0,N - + - - + + + - - - - - Ultricies + + + + + CHR - 1,1 - 0,N + 0,N + 0,N + 0,N - + - - + + - - - - - Mollis + + + + + CT - 0,N - 0,N + 1,1 + 1,N - + - - + + + - - - - - Porttitor + + + + + THR - 1,N - 1,N + 0,N + 0,N + 0,N - + - - - - + + + + - DATE - date - + Étudiant + id. étudiant + + nom étudiant - + - - - - + + + + + + Période + heure + + + + + + + + + + - Egestas - vivamus - - semper - aliquam + Niveau + niveau + - + - - - - + + + + - Vitae justo - lobortis - - purus + Cours + id. cours + + nom cours - + - - - - + + + + - Curabitur - blandit - - suscipit + Salle + id. salle + + nom salle - + - - - - + + + + - Rhoncus - dolor a - - bibendum + Période + heure + + + + + + + + + + + + Période + heure + + + + + + + + + + + + Professeur + id. professeur + + nom professeur + + + + + + + + + + + Période + heure +

@@ -28940,15 +29142,15 @@

    -
  • Adipiscing (_#blandit_, _#lobortis_, date)
  • -
  • Curabitur (blandit, suscipit)
  • -
  • Egestas (vivamus, semper, aliquam)
  • -
  • Imperdiet (_#vivamus_, _#blandit_, date)
  • -
  • Mollis (_#blandit 1_, _#blandit 2_)
  • -
  • Pharetra (_#blandit_, date, _#lobortis_, massa)
  • -
  • Porttitor (_#dolor a_, _#blandit_)
  • -
  • Rhoncus (dolor a, bibendum, #vivamus)
  • -
  • Vitae justo (lobortis, purus)
  • +
  • CHR (heure, _#id. salle_, _#id. cours_)
  • +
  • CHS (heure, _#id. cours_, _#id. étudiant_)
  • +
  • Cours (id. cours, nom cours, #id. professeur)
  • +
  • CSG (niveau, _#id. cours_, _#id. étudiant_)
  • +
  • Étudiant (id. étudiant, nom étudiant)
  • +
  • Professeur (id. professeur, nom professeur)
  • +
  • Salle (id. salle, nom salle)
  • +
  • SHR (heure, _#id. salle_, _#id. étudiant_)
  • +
  • THR (heure, _#id. salle_, _#id. professeur_)

@@ -28962,31 +29164,46 @@

-

La monnayer en deux entités DATE1 et DATE2 permettra une mise en page à la fois plus agréable à l'œil et plus compacte (à savoir, $4\times3$ au lieu de $5\times3$), le tout sans impact sur le schéma relationnel :

+

Ce genre de problème (et sa solution) se présente typiquement lorsqu'une entité DATE réduite à un identifiant date est associée à un grand nombre d'entités n'ayant rien à voir entre elles.

+ +
+
+

+
+
+
+

Par suppression de ces mêmes entités

+
+
+
+
+
+
+

Inversement, toujours étant donné que ce type d'entité est destiné à disparaître lors du passage au relationnel, on peut décider de les supprimer par anticipation. Pour cela, il faut accepter que les associations puissent être porteuses d'identifiants (ce qui n'est pas prévu par Merise). Cela permet d'obtenir ce joli schéma, toujours sans impact sur le schéma relationnel :

-
In [116]:
+
In [118]:
-
%%mocodo --flex 0 -t
-Egestas: vivamus, semper, aliquam
-DATE1: date
-Pharetra, 0N Curabitur, 0N DATE1, 0N Vitae justo: massa
-Vitae justo: lobortis, purus
-
-Ultricies, 11 Rhoncus, 0N Egestas
-Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE1
-Curabitur: blandit, suscipit
-Adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE2
-
-Rhoncus: dolor a, bibendum
-Porttitor, 1N Rhoncus, 1N Curabitur
-Mollis, 0N Curabitur, 0N Curabitur
-DATE2: date
+
%%mocodo -t
+CSG, 1N Cours, 1N Étudiant: _niveau
+:
+Cours: id. cours, nom cours
+CT, 11 Cours, 1N Professeur
+
+:
+CHS, 0N Cours, 0N Étudiant: _heure
+CHR, 0N Salle, 0N Cours: _heure
+Professeur: id. professeur, nom professeur
+    
+Étudiant: id. étudiant, nom étudiant
+SHR, 0N Salle, 0N Étudiant: _heure
+Salle: id. salle, nom salle
+THR, 0N Salle, 0N Professeur: _heure
 
@@ -29004,187 +29221,163 @@

- - + + - + - - - + + - - - - - Pharetra - massa + + + + + CSG + niveau + - 0,N - 0,N - 0,N + 1,N + 1,N - + - - + + - - - - - Ultricies + + + + + CT - 1,1 - 0,N + 1,1 + 1,N - + - - - + + - - - - - Imperdiet + + + + + CHS + heure + - 0,N - 0,N - 0,N + 0,N + 0,N - + - - - + + - - - - - Adipiscing + + + + + CHR + heure + - 0,N - 0,N - 0,N + 0,N + 0,N - + - - + + - - - - - Porttitor + + + + + SHR + heure + - 1,N - 1,N + 0,N + 0,N - + - - + + - - - - - Mollis - - 0,N - 0,N - - - - - - - - - + + + + + THR + heure + - Egestas - vivamus - - semper - aliquam + 0,N + 0,N - + - - - - - - DATE - date - - - - - - - - - - + + + + - Vitae justo - lobortis - - purus + Cours + id. cours + + nom cours - + - - - - + + + + - Curabitur - blandit - - suscipit + Professeur + id. professeur + + nom professeur - + - - - - + + + + - Rhoncus - dolor a - - bibendum + Étudiant + id. étudiant + + nom étudiant - + - - - - + + + + - DATE - date - + Salle + id. salle + + nom salle

@@ -29199,15 +29392,15 @@

    -
  • Adipiscing (_#blandit_, _#lobortis_, date)
  • -
  • Curabitur (blandit, suscipit)
  • -
  • Egestas (vivamus, semper, aliquam)
  • -
  • Imperdiet (_#vivamus_, _#blandit_, date)
  • -
  • Mollis (_#blandit 1_, _#blandit 2_)
  • -
  • Pharetra (_#blandit_, date, _#lobortis_, massa)
  • -
  • Porttitor (_#dolor a_, _#blandit_)
  • -
  • Rhoncus (dolor a, bibendum, #vivamus)
  • -
  • Vitae justo (lobortis, purus)
  • +
  • CHR (_#id. salle_, _#id. cours_, heure)
  • +
  • CHS (_#id. cours_, _#id. étudiant_, heure)
  • +
  • Cours (id. cours, nom cours, #id. professeur)
  • +
  • CSG (_#id. cours_, _#id. étudiant_, niveau)
  • +
  • Étudiant (id. étudiant, nom étudiant)
  • +
  • Professeur (id. professeur, nom professeur)
  • +
  • Salle (id. salle, nom salle)
  • +
  • SHR (_#id. salle_, _#id. étudiant_, heure)
  • +
  • THR (_#id. salle_, _#id. professeur_, heure)

@@ -29217,6 +29410,53 @@

+
+
+

Notez qu'avec cette technique, les cardinalités minimales des pattes distinguées par les entités supprimées sont perdues dès le niveau conceptuel (sachant qu'elles l'auraient été de toute façon lors du passage au relationnel).

+ +
+
+

+
+
+
+

Comme la notion d'identifiant explicite d'association enfreint le standard Merise, et risque de semer la discorde entre professeurs et étudiants, elle est par défaut désactivée sous Mocodo online. En ligne de commande, elle est interdite à la demande :

+ +
+
+
+
+
+
In [119]:
+
+
+
%mocodo -i sandbox --no_assoc_ids
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Mocodo Err.52 - L'association « CSG » ne peut pas avoir d'identifiant.
+
+
+
+ +
+
+
@@ -29242,7 +29482,7 @@

Format des cardinalités
-
In [117]:
+
In [120]:
%%mocodo  --card_format=({min_card}/{max_card}) --strengthen_card=(1/1)(R)
@@ -29336,7 +29576,7 @@ 

Format des clés étr

-
In [118]:
+
In [121]:
%mocodo -i ccp -t diagram --fk_format={label}
@@ -29376,7 +29616,7 @@ 

Format des clés étr
-

+

@@ -29403,7 +29643,7 @@

Symbole de dépendance fon

-
In [119]:
+
In [122]:
%%mocodo --df CIF
@@ -29573,7 +29813,7 @@ 

En ajoutant des liens invisibles
-
In [120]:
+
In [123]:
%%mocodo
@@ -29738,7 +29978,7 @@ 

En ajoutant une boîte invisib

-
In [121]:
+
In [124]:
%%mocodo
@@ -29913,7 +30153,7 @@ 

En ajoutant une boîte invisib

-
In [122]:
+
In [125]:
%%mocodo
@@ -30086,7 +30326,7 @@ 

Gouttière d'identifiants
-
In [123]:
+
In [126]:
%%mocodo --gutters ids:visibility=off
@@ -30146,7 +30386,7 @@ 

Gouttière d'identifiants
-
In [124]:
+
In [127]:
%%mocodo --gutters ids:visibility=on
@@ -30213,7 +30453,7 @@ 

Gouttière d'identifiants
-
In [125]:
+
In [128]:
%%mocodo --gutters ids:strong=➤,alts=❶❷❸❹
@@ -30287,7 +30527,7 @@ 

Style et direction des

-
In [126]:
+
In [129]:
%%mocodo -t
@@ -30405,7 +30645,7 @@ 

Style et direction des

-
In [127]:
+
In [130]:
%%mocodo -t
@@ -30535,7 +30775,7 @@ 

Retouches fines
-
In [128]:
+
In [131]:
%%mocodo --colors brewer+1
@@ -30648,7 +30888,7 @@ 

Retouches fines
-
In [129]:
+
In [132]:
display.Code("sandbox_geo.json")
@@ -30664,7 +30904,7 @@ 

Retouches fines -
Out[129]:
+
Out[132]:
@@ -30794,7 +31034,7 @@

Retouches fines
-
In [130]:
+
In [133]:
%%file sandbox_geo.json
@@ -30858,7 +31098,7 @@ 

Retouches fines
-
In [131]:
+
In [134]:
%mocodo -i sandbox --colors brewer+1 --reuse_geo
@@ -30987,7 +31227,7 @@ 

Conversion dans d'autres fo

-
In [132]:
+
In [135]:
%mocodo -i ccp --svg_to png pdf --select
@@ -31008,7 +31248,7 @@ 

Conversion dans d'autres fo

-
In [133]:
+
In [136]:
display.IFrame("mocodo_notebook/ccp.pdf", width="100%", height="100%")
@@ -31024,7 +31264,7 @@ 

Conversion dans d'autres fo
-
Out[133]:
+
Out[136]:
@@ -31065,7 +31305,7 @@

Conversion dans d'autres fo

-
In [134]:
+
In [137]:
display.Image("ccp.png")
@@ -31081,13 +31321,13 @@ 

Conversion dans d'autres fo
-
Out[134]:
+
Out[137]:
-
@@ -31107,7 +31347,7 @@

Conversion dans d'autres fo

-
In [135]:
+
In [138]:
display.Image("../examples/svg2roughjs.png")
@@ -31123,13 +31363,13 @@ 

Conversion dans d'autres fo
-
Out[135]:
+
Out[138]:
-
@@ -31163,7 +31403,7 @@

Décompositions d'un MCD
-
In [136]:
+
In [139]:
%%mocodo 
@@ -31257,7 +31497,7 @@ 

Vider les DF de leurs attributs
-
In [137]:
+
In [140]:
%%mocodo -t
@@ -31427,7 +31667,7 @@ 

Vider les DF de leurs attributs
-
In [138]:
+
In [141]:
%mocodo -i sandbox --mld -t drain
@@ -31605,7 +31845,7 @@ 

Décomposer les DF n-aires
-
In [139]:
+
In [142]:
%%mocodo -t
@@ -31731,7 +31971,7 @@ 

Décomposer les DF n-aires
-
In [140]:
+
In [143]:
%mocodo -i sandbox --seed=3 --mld -t split arrange:wide
@@ -31872,7 +32112,7 @@ 

Décomposer les ass

-
In [141]:
+
In [144]:
%%mocodo -t
@@ -31999,7 +32239,7 @@ 

Décomposer les ass

-
In [142]:
+
In [145]:
%mocodo -i sandbox --seed=8 --mld -t explode arrange:balanced
@@ -32157,7 +32397,7 @@ 

Décomposer les ass

-
In [143]:
+
In [146]:
%%mocodo -t
@@ -32336,7 +32576,7 @@ 

Décomposer les as

-
In [144]:
+
In [147]:
%%mocodo -t
@@ -32477,7 +32717,7 @@ 

Décomposer les as

-
In [145]:
+
In [148]:
%mocodo -i=sandbox --seed=1 --scale=0.9 --mld -t explode:arity=2 arrange:wide=9
@@ -32657,7 +32897,7 @@ 

Décomposer les as

-
In [146]:
+
In [149]:
%mocodo -i=sandbox --mld -t explode:arity=2.5 arrange:wide --seed=1
@@ -32822,7 +33062,7 @@ 

Décomposer

-
In [147]:
+
In [150]:
%mocodo -i=sandbox --mld -t explode:arity=2.5,weak arrange:wide --seed=1
@@ -32980,7 +33220,7 @@ 

Décomposer

-
In [148]:
+
In [151]:
%%mocodo -t --colors ocean
@@ -33106,7 +33346,7 @@ 

Décomposer

-
In [149]:
+
In [152]:
%mocodo -i sandbox --mld -t explode:weak arrange:wide=5 --seed 21
@@ -33256,7 +33496,7 @@ 

Décomposer

-
In [150]:
+
In [153]:
%%mocodo -t
@@ -33438,7 +33678,7 @@ 

Cardinalités minimale et ma

-
In [151]:
+
In [154]:
%%mocodo
@@ -33524,7 +33764,7 @@ 

Cardinalités minimale et ma

-
In [152]:
+
In [155]:
%mocodo -i sandbox -t chen:layout=circo --defer
@@ -33592,7 +33832,7 @@ 

Cardinalités minimale et ma

-
In [153]:
+
In [156]:
%%mocodo
@@ -33670,7 +33910,7 @@ 

Cardinalités minimale et ma

-
In [154]:
+
In [157]:
%mocodo -i sandbox -t chen:layout=circo --defer
@@ -33759,7 +33999,7 @@ 

Cardinalités minimale et ma

-
In [155]:
+
In [158]:
%%mocodo
@@ -33853,7 +34093,7 @@ 

Cardinalités minimale et ma

-
In [156]:
+
In [159]:
%mocodo -i sandbox -t chen:layout=circo --defer
@@ -33920,7 +34160,7 @@ 

Entités faibles

-
In [157]:
+
In [160]:
%%mocodo
@@ -33996,7 +34236,7 @@ 

Entités faibles

-
In [158]:
+
In [161]:
%mocodo -i sandbox -t chen:layout=circo --defer
@@ -34064,7 +34304,7 @@ 

Entités faibles

-
In [159]:
+
In [162]:
%%mocodo
@@ -34175,7 +34415,7 @@ 

Entités faibles

-
In [160]:
+
In [163]:
%mocodo -i sandbox -t chen:layout=circo,mindist=2,scale=0.6 --defer
@@ -34249,7 +34489,7 @@ 

Triplet NNN

-
In [161]:
+
In [164]:
-
In [162]:
+
In [165]:
-
In [163]:
+
In [166]:
-
In [164]:
+
In [167]:
-
In [165]:
+
In [168]:
-
In [166]:
+
In [169]:
-
In [167]:
+
In [170]:
-
In [168]:
+
In [171]:
-
In [169]:
+
In [172]:
-
In [170]:
+
In [173]:
-
In [171]:
+
In [174]:
-
In [172]:
+
In [175]:
-
In [173]:
+
In [176]:
-
In [174]:
+
In [177]:
%mocodo -i sandbox -t sql
@@ -35841,7 +36081,7 @@ 

mocodo --help
-
In [175]:
+
In [178]:
%mocodo --help
@@ -35870,7 +36110,7 @@ 

mocodo --helpmocodo --helpmocodo --helpParamétrage à long terme
-
In [176]:
+
In [179]:
# You may edit and run the following lines
@@ -36259,7 +36503,7 @@ 

Aide-mémoire des transformat

-
In [177]:
+
In [180]:
display.Markdown("../fr_cheat_sheet.md")
@@ -36275,7 +36519,7 @@ 

Aide-mémoire des transformat
-
Out[177]:
+
Out[180]:
@@ -37388,7 +37632,7 @@

Dérivation de gabarits
-
In [178]:
+
In [181]:
display.SVG("../../mocodo/resources/relation_templates/_graph.svg")
@@ -37404,7 +37648,7 @@ 

Dérivation de gabarits -
Out[178]:
+
Out[181]:
@@ -38507,7 +38751,7 @@

Dérivation de gabarits
-
In [179]:
+
In [182]:
display.Code("../../mocodo/resources/relation_templates/tex.yaml")
@@ -38523,7 +38767,7 @@ 

Dérivation de gabarits -
Out[179]:
+
Out[182]:
@@ -38635,7 +38879,7 @@

Dérivation de gabarits
-
In [180]:
+
In [183]:
display.Code("../../mocodo/resources/relation_templates/latex.yaml")
@@ -38651,7 +38895,7 @@ 

Dérivation de gabarits -
Out[180]:
+
Out[183]:
@@ -38771,7 +39015,7 @@

Dérivation de gabarits
-
In [181]:
+
In [184]:
-
In [182]:
+
In [185]:
%%mocodo -t sql
@@ -39007,7 +39251,7 @@ 

Exemples de cr&#

-
In [183]:
+
In [186]:
%%file new_sql.yaml
@@ -39049,7 +39293,7 @@ 

Exemples de cr&#

-
In [184]:
+
In [187]:
%mocodo -i sandbox -t relation:new_sql.yaml
@@ -39131,7 +39375,7 @@ 

Exemples de cr&#

-
In [185]:
+
In [188]:
%%file new_sql.yaml
@@ -39176,7 +39420,7 @@ 

Exemples de cr&#

-
In [186]:
+
In [189]:
%mocodo -i sandbox -t relation:new_sql.yaml
diff --git a/doc/fr_refman.ipynb b/doc/fr_refman.ipynb
index ae84823d..322d19fe 100644
--- a/doc/fr_refman.ipynb
+++ b/doc/fr_refman.ipynb
@@ -11,7 +11,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Mocodo 4.1.0 loaded.\n"
+      "Mocodo 4.1.1 loaded.\n"
      ]
     }
    ],
@@ -281,7 +281,7 @@
     {
      "data": {
       "text/markdown": [
-       ""
+       ""
       ],
       "text/plain": [
        ""
@@ -1221,7 +1221,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "**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). Vous n'aurez plus qu'à remplir les autres attributs :"
+    "**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 :"
    ]
   },
   {
@@ -1237,59 +1237,59 @@
        "\n",
        "\n",
        "\n",
-       "\t\n",
-       "\t\n",
-       "\t\n",
+       "\t\n",
+       "\t\n",
+       "\t\n",
        "\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\tRéserver\n",
-       "\t\tDurée\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\tRéserver\n",
+       "\t\tDurée\n",
        "\t\n",
-       "\t1,N\n",
-       "\t1,N\n",
-       "\t0,N\n",
+       "\t1,N\n",
+       "\t1,N\n",
+       "\t0,N\n",
        "\n",
        "\n",
-       "\n",
+       "\n",
        "\n",
        "\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
        "\t\n",
-       "\tClient\n",
-       "\tid. client\n",
-       "\t\n",
+       "\tDate\n",
+       "\tdate\n",
+       "\t\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
        "\t\n",
-       "\tChambre\n",
-       "\tid. chambre\n",
-       "\t\n",
+       "\tChambre\n",
+       "\tid. chambre\n",
+       "\t\n",
        "\n",
        "\n",
-       "\n",
+       "\n",
        "\n",
        "\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
-       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
        "\t\n",
-       "\tDate\n",
-       "\tdate\n",
-       "\t\n",
+       "\tClient\n",
+       "\tid. client\n",
+       "\t\n",
        "\n",
        ""
       ],
@@ -1327,9 +1327,9 @@
       "%%mocodo \n",
       "Réserver, 1N Client, 1N Chambre, 0N Date: Durée\n",
       "\n",
-      "Client: id. client, \n",
+      "Date: date\n",
       "Chambre: id. chambre, \n",
-      "Date: date\n"
+      "Client: id. client, \n"
      ]
     }
    ],
@@ -4189,6 +4189,112 @@
     "**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."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Identifiants explicites dans les associations"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "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 :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/svg+xml": [
+       "\n",
+       "\n",
+       "\n",
+       "\n",
+       "\n",
+       "\t\n",
+       "\t\n",
+       "\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\tRéserver\n",
+       "\t\tDate\n",
+       "\t\t\n",
+       "\t\tDurée\n",
+       "\t\n",
+       "\t1,N\n",
+       "\t0,N\n",
+       "\n",
+       "\n",
+       "\n",
+       "\n",
+       "\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\n",
+       "\tClient\n",
+       "\tId. client\n",
+       "\t\n",
+       "\n",
+       "\n",
+       "\n",
+       "\n",
+       "\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\t\n",
+       "\t\n",
+       "\tChambre\n",
+       "\tNum. chambre\n",
+       "\t\n",
+       "\tPrix\n",
+       "\n",
+       ""
+      ],
+      "text/plain": [
+       ""
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/markdown": [
+       "- **Chambre** (Num. chambre, Prix)\n",
+       "- **Réserver** (Id. client, _#Num. chambre_, Date, Durée)\n"
+      ],
+      "text/plain": [
+       ""
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "%%mocodo -t\n",
+    "Client: Id. client\n",
+    "Réserver, 1N Client, 0N Chambre: _Date, Durée\n",
+    "Chambre: Num. chambre, Prix"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "L'introduction de cette possibilité, surtout destinée à simplifier le plongement des MCD touffus, est discutée [ici](#Par-suppression-de-ces-mêmes-entités)."
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -4263,7 +4369,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 36,
    "metadata": {},
    "outputs": [
     {
@@ -4315,7 +4421,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 37,
    "metadata": {
     "scrolled": true
    },
@@ -4447,7 +4553,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 38,
    "metadata": {},
    "outputs": [
     {
@@ -4473,7 +4579,7 @@
     {
      "data": {
       "text/markdown": [
-       ""
+       ""
       ],
       "text/plain": [
        ""
@@ -4496,7 +4602,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 39,
    "metadata": {},
    "outputs": [
     {
@@ -4614,7 +4720,7 @@
        ":"
       ]
      },
-     "execution_count": 37,
+     "execution_count": 39,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -4672,7 +4778,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 40,
    "metadata": {},
    "outputs": [
     {
@@ -4781,7 +4887,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": 41,
    "metadata": {},
    "outputs": [
     {
@@ -4842,7 +4948,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 42,
    "metadata": {},
    "outputs": [
     {
@@ -4908,7 +5014,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 43,
    "metadata": {
     "scrolled": false
    },
@@ -4996,7 +5102,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 42,
+   "execution_count": 44,
    "metadata": {},
    "outputs": [
     {
@@ -5048,7 +5154,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 45,
    "metadata": {
     "scrolled": true
    },
@@ -5163,7 +5269,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 44,
+   "execution_count": 46,
    "metadata": {},
    "outputs": [
     {
@@ -5280,7 +5386,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
+   "execution_count": 47,
    "metadata": {},
    "outputs": [
     {
@@ -5330,7 +5436,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 46,
+   "execution_count": 48,
    "metadata": {},
    "outputs": [
     {
@@ -5445,7 +5551,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 47,
+   "execution_count": 49,
    "metadata": {},
    "outputs": [
     {
@@ -5581,7 +5687,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 48,
+   "execution_count": 50,
    "metadata": {},
    "outputs": [
     {
@@ -5686,7 +5792,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 49,
+   "execution_count": 51,
    "metadata": {},
    "outputs": [
     {
@@ -5775,7 +5881,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 50,
+   "execution_count": 52,
    "metadata": {
     "scrolled": true
    },
@@ -5934,7 +6040,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 51,
+   "execution_count": 53,
    "metadata": {},
    "outputs": [
     {
@@ -5960,7 +6066,7 @@
     {
      "data": {
       "text/markdown": [
-       ""
+       ""
       ],
       "text/plain": [
        ""
@@ -5983,7 +6089,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 52,
+   "execution_count": 54,
    "metadata": {},
    "outputs": [
     {
@@ -6072,7 +6178,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 53,
+   "execution_count": 55,
    "metadata": {},
    "outputs": [
     {
@@ -6116,7 +6222,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 54,
+   "execution_count": 56,
    "metadata": {},
    "outputs": [
     {
@@ -6244,7 +6350,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 55,
+   "execution_count": 57,
    "metadata": {},
    "outputs": [
     {
@@ -6369,7 +6475,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 56,
+   "execution_count": 58,
    "metadata": {},
    "outputs": [
     {
@@ -6544,7 +6650,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 57,
+   "execution_count": 59,
    "metadata": {},
    "outputs": [
     {
@@ -6718,7 +6824,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 58,
+   "execution_count": 60,
    "metadata": {},
    "outputs": [
     {
@@ -6850,7 +6956,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 59,
+   "execution_count": 61,
    "metadata": {},
    "outputs": [
     {
@@ -7005,7 +7111,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 60,
+   "execution_count": 62,
    "metadata": {},
    "outputs": [
     {
@@ -7201,7 +7307,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 61,
+   "execution_count": 63,
    "metadata": {},
    "outputs": [
     {
@@ -7314,7 +7420,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": 64,
    "metadata": {},
    "outputs": [
     {
@@ -7443,7 +7549,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 63,
+   "execution_count": 65,
    "metadata": {
     "scrolled": false
    },
@@ -7576,7 +7682,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 64,
+   "execution_count": 66,
    "metadata": {
     "scrolled": true
    },
@@ -7647,7 +7753,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 65,
+   "execution_count": 67,
    "metadata": {
     "scrolled": true
    },
@@ -7754,7 +7860,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 66,
+   "execution_count": 68,
    "metadata": {},
    "outputs": [
     {
@@ -7813,7 +7919,7 @@
     {
      "data": {
       "text/markdown": [
-       ""
+       ""
       ],
       "text/plain": [
        ""
@@ -7890,7 +7996,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 67,
+   "execution_count": 69,
    "metadata": {},
    "outputs": [
     {
@@ -7949,7 +8055,7 @@
     {
      "data": {
       "text/markdown": [
-       ""
+       ""
       ],
       "text/plain": [
        ""
@@ -8025,7 +8131,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 68,
+   "execution_count": 70,
    "metadata": {},
    "outputs": [
     {
@@ -8199,7 +8305,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 69,
+   "execution_count": 71,
    "metadata": {},
    "outputs": [
     {
@@ -8266,7 +8372,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 70,
+   "execution_count": 72,
    "metadata": {},
    "outputs": [
     {
@@ -8349,7 +8455,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 71,
+   "execution_count": 73,
    "metadata": {
     "scrolled": true
    },
@@ -8363,7 +8469,7 @@
        ""
       ]
      },
-     "execution_count": 71,
+     "execution_count": 73,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -8388,7 +8494,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 72,
+   "execution_count": 74,
    "metadata": {},
    "outputs": [
     {
@@ -8461,7 +8567,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 73,
+   "execution_count": 75,
    "metadata": {
     "scrolled": false
    },
@@ -8526,7 +8632,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 74,
+   "execution_count": 76,
    "metadata": {
     "scrolled": false
    },
@@ -8605,7 +8711,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 75,
+   "execution_count": 77,
    "metadata": {
     "scrolled": false
    },
@@ -8677,7 +8783,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 76,
+   "execution_count": 78,
    "metadata": {},
    "outputs": [
     {
@@ -8719,7 +8825,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 77,
+   "execution_count": 79,
    "metadata": {},
    "outputs": [
     {
@@ -8775,7 +8881,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 78,
+   "execution_count": 80,
    "metadata": {},
    "outputs": [
     {
@@ -8846,7 +8952,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 79,
+   "execution_count": 81,
    "metadata": {},
    "outputs": [
     {
@@ -8873,94 +8979,94 @@
      "data": {
       "text/html": [
        "\n",
-       "\n",
+       "
\n", " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
 Entité ou associationLibellé de l'attributTypeEntité ou associationLibellé de l'attributType
0ClientAdresseVARCHAR(255)0ClientAdresseVARCHAR(255)
1ClientNomVARCHAR(255)1ClientNomVARCHAR(255)
2ClientPrénomVARCHAR(255)2ClientPrénomVARCHAR(255)
3ClientRéf. clientVARCHAR(8)3ClientRéf. clientVARCHAR(8)
4CommandeDateDATE4CommandeDateDATE
5CommandeMontantDECIMAL(10,2)5CommandeMontantDECIMAL(10,2)
6CommandeNum. commandeVARCHAR(8)6CommandeNum. commandeVARCHAR(8)
7InclureQuantitéINTEGER7InclureQuantitéINTEGER
8ProduitLibelléVARCHAR(50)8ProduitLibelléVARCHAR(50)
9ProduitPrix unitaireDECIMAL(10,2)9ProduitPrix unitaireDECIMAL(10,2)
10ProduitRéf. produitVARCHAR(8)10ProduitRéf. produitVARCHAR(8)
\n" ], "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -8990,7 +9096,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 82, "metadata": {}, "outputs": [ { @@ -9055,7 +9161,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 83, "metadata": {}, "outputs": [ { @@ -9130,7 +9236,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 84, "metadata": {}, "outputs": [ { @@ -9191,7 +9297,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 85, "metadata": {}, "outputs": [ { @@ -9384,7 +9490,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 86, "metadata": { "scrolled": false }, @@ -9554,7 +9660,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 87, "metadata": { "scrolled": false }, @@ -9716,7 +9822,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 88, "metadata": {}, "outputs": [ { @@ -9899,7 +10005,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 89, "metadata": {}, "outputs": [ { @@ -10071,7 +10177,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 90, "metadata": {}, "outputs": [ { @@ -10141,7 +10247,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 91, "metadata": {}, "outputs": [ { @@ -10218,7 +10324,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 92, "metadata": {}, "outputs": [ { @@ -10288,7 +10394,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 93, "metadata": {}, "outputs": [ { @@ -10372,7 +10478,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 94, "metadata": {}, "outputs": [ { @@ -10465,7 +10571,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 95, "metadata": {}, "outputs": [ { @@ -10582,7 +10688,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 96, "metadata": { "scrolled": true }, @@ -10711,7 +10817,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 97, "metadata": { "scrolled": false }, @@ -10835,7 +10941,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 98, "metadata": {}, "outputs": [ { @@ -10943,7 +11049,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 99, "metadata": {}, "outputs": [ { @@ -11076,7 +11182,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 100, "metadata": {}, "outputs": [ { @@ -11184,7 +11290,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 101, "metadata": {}, "outputs": [ { @@ -11321,7 +11427,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 102, "metadata": {}, "outputs": [ { @@ -11542,7 +11648,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 103, "metadata": {}, "outputs": [ { @@ -11924,7 +12030,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 104, "metadata": { "scrolled": false }, @@ -12036,7 +12142,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 105, "metadata": {}, "outputs": [ { @@ -12045,7 +12151,7 @@ "False" ] }, - "execution_count": 103, + "execution_count": 105, "metadata": {}, "output_type": "execute_result" } @@ -12065,7 +12171,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 106, "metadata": {}, "outputs": [ { @@ -12139,7 +12245,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 107, "metadata": {}, "outputs": [ { @@ -12148,7 +12254,7 @@ "True" ] }, - "execution_count": 105, + "execution_count": 107, "metadata": {}, "output_type": "execute_result" } @@ -12270,7 +12376,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 108, "metadata": { "scrolled": false }, @@ -12548,7 +12654,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 109, "metadata": {}, "outputs": [ { @@ -12817,7 +12923,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 110, "metadata": {}, "outputs": [ { @@ -13128,7 +13234,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 111, "metadata": {}, "outputs": [ { @@ -13399,7 +13505,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 112, "metadata": {}, "outputs": [ { @@ -13533,7 +13639,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 113, "metadata": {}, "outputs": [ { @@ -13558,7 +13664,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 114, "metadata": {}, "outputs": [ { @@ -13602,7 +13708,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 115, "metadata": {}, "outputs": [ { @@ -13763,7 +13869,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 116, "metadata": {}, "outputs": [ { @@ -13912,194 +14018,266 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Amélioration du plongement par création d'entités homonymes" + "## Amélioration du plongement" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Une entité liée à de nombreuses associations peut limiter ou même empêcher les possibilités de réarrangement sans croisements. Lorsque cette entité est indépendante et réduite à son identifiant, elle est vouée à disparaître lors du passage au relationnel. Il n'y a donc 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.\n", + "Une entité liée à de nombreuses associations peut limiter ou même empêcher les possibilités de réarrangement sans croisements." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Par duplication d'entités réduites à leur identifiant" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lorsque cette entité est indépendante et réduite à son identifiant, elle est vouée à disparaître lors du passage au relationnel. Il n'y a donc 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.\n", + "\n", + "Prenons comme exemple un MCD extrait d'une [étude de François de Sainte Marie](https://fsmrel.developpez.com/basesrelationnelles/ullman-cthrsg/), et présenté comme suit :\n", "\n", - "Le cas typique est celui d'une entité DATE réduite à un identifiant _date_, qui peut être associée à un grand nombre d'entités n'ayant rien à voir entre elles. Même avec une arité très modeste de 3, elle peut perturber le plongement :" + "![](examples/ullman_cthrsg_mcd_sans_cif_80.png)\n", + "\n", + "Le graphe sous-jacent étant non planaire, des croisements sont inévitables (ici entre certaines pattes des associations SHR, CT et THR). Cependant, cette non-planarité résulte elle-même de la mise en jeu d'une même entité Période dans quatre associations triples. La monnayer en quatre entités Période numérotées augmente l'ordre du graphe, mais le rend planaire, le tout sans impact sur le schéma relationnel :" ] }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 117, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "\n", - "\n", + "\n", + "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tAdipiscing\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tSHR\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tPharetra\n", - "\t\tmassa\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCSG\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t1,N\n", + "\t1,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tImperdiet\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCHS\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tUltricies\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCHR\n", "\t\n", - "\t1,1\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tMollis\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCT\n", "\t\n", - "\t0,N\n", - "\t0,N\n", + "\t1,1\n", + "\t1,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tPorttitor\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tTHR\n", "\t\n", - "\t1,N\n", - "\t1,N\n", + "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", + "\n", + "\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\n", + "\tÉtudiant\n", + "\tid. étudiant\n", + "\t\n", + "\tnom étudiant\n", + "\n", + "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tDATE\n", - "\tdate\n", - "\t\n", + "\tPériode\n", + "\theure\n", + "\t\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\n", + "\tNiveau\n", + "\tniveau\n", + "\t\n", + "\n", + "\n", + "\n", + "\n", + "\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\n", + "\tCours\n", + "\tid. cours\n", + "\t\n", + "\tnom cours\n", + "\n", + "\n", + "\n", + "\n", + "\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\n", + "\tSalle\n", + "\tid. salle\n", + "\t\n", + "\tnom salle\n", + "\n", + "\n", + "\n", + "\n", + "\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tEgestas\n", - "\tvivamus\n", - "\t\n", - "\tsemper\n", - "\taliquam\n", + "\tPériode\n", + "\theure\n", + "\t\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tVitae justo\n", - "\tlobortis\n", - "\t\n", - "\tpurus\n", + "\tPériode\n", + "\theure\n", + "\t\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tCurabitur\n", - "\tblandit\n", - "\t\n", - "\tsuscipit\n", + "\tProfesseur\n", + "\tid. professeur\n", + "\t\n", + "\tnom professeur\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tRhoncus\n", - "\tdolor a\n", - "\t\n", - "\tbibendum\n", + "\tPériode\n", + "\theure\n", + "\t\n", "\n", "" ], @@ -14113,15 +14291,15 @@ { "data": { "text/markdown": [ - "- **Adipiscing** (_#blandit_, _#lobortis_, date)\n", - "- **Curabitur** (blandit, suscipit)\n", - "- **Egestas** (vivamus, semper, aliquam)\n", - "- **Imperdiet** (_#vivamus_, _#blandit_, date)\n", - "- **Mollis** (_#blandit 1_, _#blandit 2_)\n", - "- **Pharetra** (_#blandit_, date, _#lobortis_, massa)\n", - "- **Porttitor** (_#dolor a_, _#blandit_)\n", - "- **Rhoncus** (dolor a, bibendum, _#vivamus_)\n", - "- **Vitae justo** (lobortis, purus)\n" + "- **CHR** (heure, _#id. salle_, _#id. cours_)\n", + "- **CHS** (heure, _#id. cours_, _#id. étudiant_)\n", + "- **Cours** (id. cours, nom cours, _#id. professeur_)\n", + "- **CSG** (niveau, _#id. cours_, _#id. étudiant_)\n", + "- **Étudiant** (id. étudiant, nom étudiant)\n", + "- **Professeur** (id. professeur, nom professeur)\n", + "- **Salle** (id. salle, nom salle)\n", + "- **SHR** (heure, _#id. salle_, _#id. étudiant_)\n", + "- **THR** (heure, _#id. salle_, _#id. professeur_)\n" ], "text/plain": [ "" @@ -14133,223 +14311,221 @@ ], "source": [ "%%mocodo -t\n", + "Étudiant: id. étudiant, nom étudiant\n", ":\n", ":\n", - "DATE: date\n", - "Egestas: vivamus, semper, aliquam\n", + "SHR, 0N Période3, 0N Salle, 0N Étudiant\n", + "Période3: heure\n", + "\n", + ":\n", + "CSG, 0N Niveau, 1N Cours, 1N Étudiant\n", + "Niveau: niveau\n", ":\n", "\n", - "Adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE\n", - "Vitae justo: lobortis, purus\n", - "Pharetra, 0N Curabitur, 0N DATE, 0N Vitae justo: massa\n", - "Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE\n", - "Ultricies, 11 Rhoncus, 0N Egestas\n", + "CHS, 0N Période2, 0N Cours, 0N Étudiant\n", + "Cours: id. cours, nom cours\n", + "CHR, 0N Période4, 0N Salle, 0N Cours\n", + "Salle: id. salle, nom salle\n", "\n", + "Période2: heure\n", + "CT, 11 Cours, 1N Professeur\n", + "Période4: heure\n", + ":\n", + ":\n", + "\n", + ":\n", + "Professeur: id. professeur, nom professeur\n", ":\n", - "Mollis, 0N Curabitur, 0N Curabitur\n", - "Curabitur: blandit, suscipit\n", - "Porttitor, 1N Rhoncus, 1N Curabitur\n", - "Rhoncus: dolor a, bibendum" + "THR, 0N Période1, 0N Salle, 0N Professeur\n", + "Période1: heure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "La monnayer en deux entités DATE1 et DATE2 permettra une mise en page à la fois plus agréable à l'œil et plus compacte (à savoir, $4\\times3$ au lieu de $5\\times3$), le tout sans impact sur le schéma relationnel :" + "Ce genre de problème (et sa solution) se présente typiquement lorsqu'une entité DATE réduite à un identifiant _date_ est associée à un grand nombre d'entités n'ayant rien à voir entre elles. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Par suppression de ces mêmes entités" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inversement, toujours étant donné que ce type d'entité est destiné à disparaître lors du passage au relationnel, on peut décider de les supprimer par anticipation. Pour cela, il faut accepter que les associations puissent être porteuses d'identifiants (ce qui n'est pas prévu par Merise). Cela permet d'obtenir ce joli schéma, toujours sans impact sur le schéma relationnel :" ] }, { "cell_type": "code", - "execution_count": 116, - "metadata": { - "scrolled": false - }, + "execution_count": 118, + "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "\n", - "\n", + "\n", + "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tPharetra\n", - "\t\tmassa\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCSG\n", + "\t\tniveau\n", + "\t\t\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t1,N\n", + "\t1,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tUltricies\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCT\n", "\t\n", - "\t1,1\n", - "\t0,N\n", + "\t1,1\n", + "\t1,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tImperdiet\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCHS\n", + "\t\theure\n", + "\t\t\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tAdipiscing\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tCHR\n", + "\t\theure\n", + "\t\t\n", "\t\n", - "\t0,N\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tPorttitor\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tSHR\n", + "\t\theure\n", + "\t\t\n", "\t\n", - "\t1,N\n", - "\t1,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\tMollis\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\tTHR\n", + "\t\theure\n", + "\t\t\n", "\t\n", - "\t0,N\n", - "\t0,N\n", + "\t0,N\n", + "\t0,N\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\n", - "\tEgestas\n", - "\tvivamus\n", - "\t\n", - "\tsemper\n", - "\taliquam\n", - "\n", - "\n", - "\n", - "\n", - "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\n", - "\tDATE\n", - "\tdate\n", - "\t\n", - "\n", - "\n", - "\n", - "\n", - "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tVitae justo\n", - "\tlobortis\n", - "\t\n", - "\tpurus\n", + "\tCours\n", + "\tid. cours\n", + "\t\n", + "\tnom cours\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tCurabitur\n", - "\tblandit\n", - "\t\n", - "\tsuscipit\n", + "\tProfesseur\n", + "\tid. professeur\n", + "\t\n", + "\tnom professeur\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tRhoncus\n", - "\tdolor a\n", - "\t\n", - "\tbibendum\n", + "\tÉtudiant\n", + "\tid. étudiant\n", + "\t\n", + "\tnom étudiant\n", "\n", "\n", - "\n", + "\n", "\n", "\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", - "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", + "\t\t\n", "\t\n", - "\tDATE\n", - "\tdate\n", - "\t\n", + "\tSalle\n", + "\tid. salle\n", + "\t\n", + "\tnom salle\n", "\n", "" ], @@ -14363,15 +14539,15 @@ { "data": { "text/markdown": [ - "- **Adipiscing** (_#blandit_, _#lobortis_, date)\n", - "- **Curabitur** (blandit, suscipit)\n", - "- **Egestas** (vivamus, semper, aliquam)\n", - "- **Imperdiet** (_#vivamus_, _#blandit_, date)\n", - "- **Mollis** (_#blandit 1_, _#blandit 2_)\n", - "- **Pharetra** (_#blandit_, date, _#lobortis_, massa)\n", - "- **Porttitor** (_#dolor a_, _#blandit_)\n", - "- **Rhoncus** (dolor a, bibendum, _#vivamus_)\n", - "- **Vitae justo** (lobortis, purus)\n" + "- **CHR** (_#id. salle_, _#id. cours_, heure)\n", + "- **CHS** (_#id. cours_, _#id. étudiant_, heure)\n", + "- **Cours** (id. cours, nom cours, _#id. professeur_)\n", + "- **CSG** (_#id. cours_, _#id. étudiant_, niveau)\n", + "- **Étudiant** (id. étudiant, nom étudiant)\n", + "- **Professeur** (id. professeur, nom professeur)\n", + "- **Salle** (id. salle, nom salle)\n", + "- **SHR** (_#id. salle_, _#id. étudiant_, heure)\n", + "- **THR** (_#id. salle_, _#id. professeur_, heure)\n" ], "text/plain": [ "" @@ -14382,21 +14558,52 @@ } ], "source": [ - "%%mocodo --flex 0 -t\n", - "Egestas: vivamus, semper, aliquam\n", - "DATE1: date\n", - "Pharetra, 0N Curabitur, 0N DATE1, 0N Vitae justo: massa\n", - "Vitae justo: lobortis, purus\n", - "\n", - "Ultricies, 11 Rhoncus, 0N Egestas\n", - "Imperdiet, 0N Egestas, 0N Curabitur, 0N DATE1\n", - "Curabitur: blandit, suscipit\n", - "Adipiscing, 0N Curabitur, 0N Vitae justo, 0N DATE2\n", + "%%mocodo -t\n", + "CSG, 1N Cours, 1N Étudiant: _niveau\n", + ":\n", + "Cours: id. cours, nom cours\n", + "CT, 11 Cours, 1N Professeur\n", "\n", - "Rhoncus: dolor a, bibendum\n", - "Porttitor, 1N Rhoncus, 1N Curabitur\n", - "Mollis, 0N Curabitur, 0N Curabitur\n", - "DATE2: date" + ":\n", + "CHS, 0N Cours, 0N Étudiant: _heure\n", + "CHR, 0N Salle, 0N Cours: _heure\n", + "Professeur: id. professeur, nom professeur\n", + " \n", + "Étudiant: id. étudiant, nom étudiant\n", + "SHR, 0N Salle, 0N Étudiant: _heure\n", + "Salle: id. salle, nom salle\n", + "THR, 0N Salle, 0N Professeur: _heure" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notez qu'avec cette technique, les cardinalités minimales des pattes distinguées par les entités supprimées sont perdues dès le niveau conceptuel (sachant qu'elles l'auraient été de toute façon lors du passage au relationnel)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Comme la notion d'identifiant explicite d'association enfreint le standard Merise, et risque de semer la discorde entre professeurs et étudiants, elle est par défaut désactivée sous Mocodo online. En ligne de commande, elle est interdite à la demande :" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Mocodo Err.52 - L'association « CSG » ne peut pas avoir d'identifiant.\n" + ] + } + ], + "source": [ + "%mocodo -i sandbox --no_assoc_ids" ] }, { @@ -14422,7 +14629,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 120, "metadata": { "scrolled": true }, @@ -14507,7 +14714,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 121, "metadata": {}, "outputs": [ { @@ -14533,7 +14740,7 @@ { "data": { "text/markdown": [ - "" + "" ], "text/plain": [ "" @@ -14563,7 +14770,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 122, "metadata": {}, "outputs": [ { @@ -14722,7 +14929,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 123, "metadata": { "scrolled": false }, @@ -14878,7 +15085,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 124, "metadata": {}, "outputs": [ { @@ -15042,7 +15249,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 125, "metadata": {}, "outputs": [ { @@ -15203,7 +15410,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 126, "metadata": {}, "outputs": [ { @@ -15252,7 +15459,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 127, "metadata": {}, "outputs": [ { @@ -15308,7 +15515,7 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 128, "metadata": { "scrolled": true }, @@ -15373,7 +15580,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 129, "metadata": {}, "outputs": [ { @@ -15478,7 +15685,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 130, "metadata": { "scrolled": false }, @@ -15595,7 +15802,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 131, "metadata": {}, "outputs": [ { @@ -15697,7 +15904,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 132, "metadata": {}, "outputs": [ { @@ -15860,7 +16067,7 @@ "}" ] }, - "execution_count": 129, + "execution_count": 132, "metadata": {}, "output_type": "execute_result" } @@ -15885,7 +16092,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 133, "metadata": {}, "outputs": [ { @@ -15934,7 +16141,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 134, "metadata": {}, "outputs": [ { @@ -16050,7 +16257,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 135, "metadata": {}, "outputs": [], "source": [ @@ -16066,7 +16273,7 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 136, "metadata": { "scrolled": true }, @@ -16086,10 +16293,10 @@ " " ], "text/plain": [ - "" + "" ] }, - "execution_count": 133, + "execution_count": 136, "metadata": {}, "output_type": "execute_result" } @@ -16114,7 +16321,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 137, "metadata": { "scrolled": true }, @@ -16126,7 +16333,7 @@ "" ] }, - "execution_count": 134, + "execution_count": 137, "metadata": {}, "output_type": "execute_result" } @@ -16144,7 +16351,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 138, "metadata": {}, "outputs": [ { @@ -16154,7 +16361,7 @@ "" ] }, - "execution_count": 135, + "execution_count": 138, "metadata": {}, "output_type": "execute_result" } @@ -16186,7 +16393,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 139, "metadata": {}, "outputs": [ { @@ -16269,7 +16476,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 140, "metadata": { "scrolled": true }, @@ -16427,7 +16634,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 141, "metadata": {}, "outputs": [ { @@ -16590,7 +16797,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 142, "metadata": {}, "outputs": [ { @@ -16702,7 +16909,7 @@ }, { "cell_type": "code", - "execution_count": 140, + "execution_count": 143, "metadata": {}, "outputs": [ { @@ -16829,7 +17036,7 @@ }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 144, "metadata": {}, "outputs": [ { @@ -16942,7 +17149,7 @@ }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 145, "metadata": {}, "outputs": [ { @@ -17084,7 +17291,7 @@ }, { "cell_type": "code", - "execution_count": 143, + "execution_count": 146, "metadata": {}, "outputs": [ { @@ -17249,7 +17456,7 @@ }, { "cell_type": "code", - "execution_count": 144, + "execution_count": 147, "metadata": {}, "outputs": [ { @@ -17376,7 +17583,7 @@ }, { "cell_type": "code", - "execution_count": 145, + "execution_count": 148, "metadata": {}, "outputs": [ { @@ -17542,7 +17749,7 @@ }, { "cell_type": "code", - "execution_count": 146, + "execution_count": 149, "metadata": {}, "outputs": [ { @@ -17693,7 +17900,7 @@ }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 150, "metadata": {}, "outputs": [ { @@ -17837,7 +18044,7 @@ }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 151, "metadata": {}, "outputs": [ { @@ -17949,7 +18156,7 @@ }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 152, "metadata": {}, "outputs": [ { @@ -18085,7 +18292,7 @@ }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 153, "metadata": {}, "outputs": [ { @@ -18250,7 +18457,7 @@ }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 154, "metadata": {}, "outputs": [ { @@ -18325,7 +18532,7 @@ }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 155, "metadata": {}, "outputs": [ { @@ -18381,7 +18588,7 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 156, "metadata": {}, "outputs": [ { @@ -18449,7 +18656,7 @@ }, { "cell_type": "code", - "execution_count": 154, + "execution_count": 157, "metadata": {}, "outputs": [ { @@ -18512,7 +18719,7 @@ }, { "cell_type": "code", - "execution_count": 155, + "execution_count": 158, "metadata": {}, "outputs": [ { @@ -18596,7 +18803,7 @@ }, { "cell_type": "code", - "execution_count": 156, + "execution_count": 159, "metadata": { "scrolled": true }, @@ -18654,7 +18861,7 @@ }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 160, "metadata": {}, "outputs": [ { @@ -18720,7 +18927,7 @@ }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 161, "metadata": {}, "outputs": [ { @@ -18776,7 +18983,7 @@ }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 162, "metadata": {}, "outputs": [ { @@ -18876,7 +19083,7 @@ }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 163, "metadata": {}, "outputs": [ { @@ -18939,7 +19146,7 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 164, "metadata": { "scrolled": true }, @@ -19045,7 +19252,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 165, "metadata": { "scrolled": false }, @@ -19114,7 +19321,7 @@ }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 166, "metadata": {}, "outputs": [ { @@ -19186,7 +19393,7 @@ }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 167, "metadata": {}, "outputs": [ { @@ -19288,7 +19495,7 @@ }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 168, "metadata": {}, "outputs": [ { @@ -19398,7 +19605,7 @@ }, { "cell_type": "code", - "execution_count": 166, + "execution_count": 169, "metadata": {}, "outputs": [ { @@ -19543,7 +19750,7 @@ }, { "cell_type": "code", - "execution_count": 167, + "execution_count": 170, "metadata": {}, "outputs": [ { @@ -19617,7 +19824,7 @@ }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 171, "metadata": {}, "outputs": [ { @@ -19735,7 +19942,7 @@ }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 172, "metadata": {}, "outputs": [ { @@ -19876,7 +20083,7 @@ }, { "cell_type": "code", - "execution_count": 170, + "execution_count": 173, "metadata": {}, "outputs": [ { @@ -19941,7 +20148,7 @@ }, { "cell_type": "code", - "execution_count": 171, + "execution_count": 174, "metadata": {}, "outputs": [ { @@ -20009,7 +20216,7 @@ }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 175, "metadata": {}, "outputs": [ { @@ -20130,7 +20337,7 @@ }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 176, "metadata": {}, "outputs": [ { @@ -20282,7 +20489,7 @@ }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 177, "metadata": {}, "outputs": [ { @@ -20373,7 +20580,7 @@ }, { "cell_type": "code", - "execution_count": 175, + "execution_count": 178, "metadata": { "scrolled": false }, @@ -20391,7 +20598,7 @@ " [--seed [FLOAT]] [--title STR] [--df STR] [--card_format [STR]]\n", " [--fk_format [STR]] [--strengthen_card [STR]] [--flex FLOAT]\n", " [--colors STEM_OR_PATH] [--shapes STEM_OR_PATH] [--scale RATE]\n", - " [--adjust_width RATE] [--detect_overlaps]\n", + " [--adjust_width RATE] [--detect_overlaps] [--no_assoc_ids]\n", " [--gutters STR [STR ...]]\n", "\n", "NOM :\n", @@ -20432,7 +20639,8 @@ " répertoire (default: /Users/aristide/Dropbox/Sites/moc\n", " odo/doc/mocodo_notebook/sandbox.mcd)\n", " --lib [URL] remote directory to use as fallback when the input\n", - " file is not found locally (default: None)\n", + " file is not found locally (default:\n", + " https://mocodo.net/web/lib)\n", " --output_dir PATH le répertoire des fichiers de sortie (default: .)\n", " --encodings [STR ...]\n", " un ou plusieurs encodages à essayer successivement\n", @@ -20499,6 +20707,9 @@ " à l'échelle donné (default: 1)\n", " --detect_overlaps lève une erreur quand des pattes horizontales ou\n", " verticales se chevauchent (default: False)\n", + " --no_assoc_ids interdit l'utilisation d'identifiants dans les\n", + " associations (conformément au standard Merise)\n", + " (default: False)\n", " --gutters STR [STR ...]\n", " définit la visibilité et le contenu des gouttières\n", " latérales\n", @@ -20556,7 +20767,7 @@ }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 179, "metadata": {}, "outputs": [], "source": [ @@ -20772,7 +20983,7 @@ }, { "cell_type": "code", - "execution_count": 177, + "execution_count": 180, "metadata": { "scrolled": false }, @@ -20938,7 +21149,7 @@ "" ] }, - "execution_count": 177, + "execution_count": 180, "metadata": {}, "output_type": "execute_result" } @@ -21116,7 +21327,7 @@ }, { "cell_type": "code", - "execution_count": 178, + "execution_count": 181, "metadata": { "scrolled": false }, @@ -22209,7 +22420,7 @@ "" ] }, - "execution_count": 178, + "execution_count": 181, "metadata": {}, "output_type": "execute_result" } @@ -22227,7 +22438,7 @@ }, { "cell_type": "code", - "execution_count": 179, + "execution_count": 182, "metadata": {}, "outputs": [ { @@ -22318,7 +22529,7 @@ "parent: 'latex'" ] }, - "execution_count": 179, + "execution_count": 182, "metadata": {}, "output_type": "execute_result" } @@ -22348,7 +22559,7 @@ }, { "cell_type": "code", - "execution_count": 180, + "execution_count": 183, "metadata": {}, "outputs": [ { @@ -22502,7 +22713,7 @@ "add_optionality_constraints:" ] }, - "execution_count": 180, + "execution_count": 183, "metadata": {}, "output_type": "execute_result" } @@ -22520,7 +22731,7 @@ }, { "cell_type": "code", - "execution_count": 181, + "execution_count": 184, "metadata": {}, "outputs": [ { @@ -22704,7 +22915,7 @@ " replace: '$^{\\1}$'" ] }, - "execution_count": 181, + "execution_count": 184, "metadata": {}, "output_type": "execute_result" } @@ -22736,7 +22947,7 @@ }, { "cell_type": "code", - "execution_count": 182, + "execution_count": 185, "metadata": {}, "outputs": [ { @@ -22802,7 +23013,7 @@ }, { "cell_type": "code", - "execution_count": 183, + "execution_count": 186, "metadata": {}, "outputs": [ { @@ -22829,7 +23040,7 @@ }, { "cell_type": "code", - "execution_count": 184, + "execution_count": 187, "metadata": {}, "outputs": [ { @@ -22901,7 +23112,7 @@ }, { "cell_type": "code", - "execution_count": 185, + "execution_count": 188, "metadata": {}, "outputs": [ { @@ -22931,7 +23142,7 @@ }, { "cell_type": "code", - "execution_count": 186, + "execution_count": 189, "metadata": { "scrolled": false }, diff --git a/index.php b/index.php index 56c939c5..42f7aa44 100644 --- a/index.php +++ b/index.php @@ -311,7 +311,7 @@
diff --git a/test/zoo/inheritance/mld/inheritance_2_mld.tex b/test/zoo/inheritance/mld/inheritance_2_mld.tex index 3a9d853a..8a790afd 100644 --- a/test/zoo/inheritance/mld/inheritance_2_mld.tex +++ b/test/zoo/inheritance/mld/inheritance_2_mld.tex @@ -18,7 +18,7 @@ \begin{itemize} \item \relat{ALIQUET} (\prim{magna}, \foreign{\prim{tellus}}, \attr{type!}) \begin{itemize} - \item Le champ \emph{magna} fait partie de la clé primaire de la table. Il a migré par l'association de dépendance fonctionnelle \emph{ALIQUET} à partir de l'entité \emph{TRISTIS} (supprimée). **Attention** : aucune contrainte d'intégrité référentielle n'est plus assurée. + \item Le champ \emph{magna} fait partie de la clé primaire de la table. Il a migré par l'association de dépendance fonctionnelle \emph{ALIQUET} à partir de l'entité \emph{TRISTIS} (supprimée). \paragraph{Attention} : aucune contrainte d'intégrité référentielle n'est plus assurée. \item Le champ \emph{tellus} fait partie de la clé primaire de la table. C'est une clé étrangère qui a migré directement à partir de l'entité \emph{DIGNISSIM}. \item Un discriminateur à saisie obligatoire \emph{type} est ajouté pour indiquer la nature de la spécialisation. Jamais vide, du fait de la contrainte de totalité. \end{itemize} @@ -83,7 +83,7 @@ \begin{itemize} \item Le champ \emph{orci} constitue la clé primaire de la table. C'était déjà un identifiant de l'entité \emph{SUSCIPIT}. \item Le champ \emph{lorem} était déjà un simple attribut de l'entité \emph{SUSCIPIT}. - \item Le champ à saisie obligatoire \emph{magna} a migré par l'association de dépendance fonctionnelle \emph{RHONCUS} à partir de l'entité \emph{TRISTIS} (supprimée). **Attention** : aucune contrainte d'intégrité référentielle n'est plus assurée. + \item Le champ à saisie obligatoire \emph{magna} a migré par l'association de dépendance fonctionnelle \emph{RHONCUS} à partir de l'entité \emph{TRISTIS} (supprimée). \paragraph{Attention} : aucune contrainte d'intégrité référentielle n'est plus assurée. \item Un discriminateur à saisie obligatoire \emph{type} est ajouté pour indiquer la nature de la spécialisation. Jamais vide, du fait de la contrainte de totalité. \end{itemize} diff --git a/test/zoo/inheritance/mld/inheritance_2_mld.txt b/test/zoo/inheritance/mld/inheritance_2_mld.txt index 8ed77402..ee369179 100644 --- a/test/zoo/inheritance/mld/inheritance_2_mld.txt +++ b/test/zoo/inheritance/mld/inheritance_2_mld.txt @@ -1,5 +1,5 @@ - ALIQUET (_magna_, _#tellus_, type!) - - Le champ « magna » fait partie de la clé primaire de la table. Il a migré par l'association de dépendance fonctionnelle « ALIQUET » à partir de l'entité « TRISTIS » (supprimée). **Attention** : aucune contrainte d'intégrité référentielle n'est plus assurée. + - Le champ « magna » fait partie de la clé primaire de la table. Il a migré par l'association de dépendance fonctionnelle « ALIQUET » à partir de l'entité « TRISTIS » (supprimée). Attention : aucune contrainte d'intégrité référentielle n'est plus assurée. - Le champ « tellus » fait partie de la clé primaire de la table. C'est une clé étrangère qui a migré directement à partir de l'entité « DIGNISSIM ». - Un discriminateur à saisie obligatoire « type » est ajouté pour indiquer la nature de la spécialisation. Jamais vide, du fait de la contrainte de totalité. @@ -46,7 +46,7 @@ - SUSCIPIT (_orci_, lorem, magna!, type!) - Le champ « orci » constitue la clé primaire de la table. C'était déjà un identifiant de l'entité « SUSCIPIT ». - Le champ « lorem » était déjà un simple attribut de l'entité « SUSCIPIT ». - - Le champ à saisie obligatoire « magna » a migré par l'association de dépendance fonctionnelle « RHONCUS » à partir de l'entité « TRISTIS » (supprimée). **Attention** : aucune contrainte d'intégrité référentielle n'est plus assurée. + - Le champ à saisie obligatoire « magna » a migré par l'association de dépendance fonctionnelle « RHONCUS » à partir de l'entité « TRISTIS » (supprimée). Attention : aucune contrainte d'intégrité référentielle n'est plus assurée. - Un discriminateur à saisie obligatoire « type » est ajouté pour indiquer la nature de la spécialisation. Jamais vide, du fait de la contrainte de totalité. - ULTRICES (_#posuere_, _#magna_) diff --git a/web/generate.php b/web/generate.php index a0117534..15f6e291 100644 --- a/web/generate.php +++ b/web/generate.php @@ -115,6 +115,10 @@ $mocodo .= " -t{$transformation_options}"; }; +if (!in_array("assoc_ids", $_POST["knowledge"])) { + $mocodo .= " --no_assoc_ids"; +}; + // Launch the script $out = array(); diff --git a/web/mocodo.js b/web/mocodo.js index ba9c6d6c..d958e0e4 100644 --- a/web/mocodo.js +++ b/web/mocodo.js @@ -111,6 +111,11 @@ var knowledge = { "title": "Cochez pour faire apparaître dans le schéma relationnel les contraintes d'unicité en exposant, d'optionalité comme des « ? », et de non-optionalité comme des « ! ». Ces notations sont non standard et peuvent gêner la lecture. NB : quel que soit votre choix, Mocodo ajoute systématiquement les contraintes UNIQUE, NULL ou NOT NULL appropriées dans le code SQL généré.", "default": false }, + "assoc_ids": { + "name": "Autoriser les identifiants dans les associations", + "title": "Cochez pour activer cette possibilité, non prévue par Merise, mais qui permet dans certains cas de produire un même schéma relationnel à partir d'un schéma conceptuel plus simple.", + "default": false + }, "reproductibility": { "name": "Reproductibilité des résultats", "title": "Cochez pour que la longueur de la première ligne du texte-source soit prise comme germe du générateur aléatoire. Ainsi, les algorithmes randomisés produiront toujours la même sortie sur un même texte-source.",