Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mécanisme de suppression des tables indépendantes réduites à leur clé primaire #66

Closed
fduchatea opened this issue Nov 21, 2022 · 12 comments · Fixed by #70
Closed

Comments

@fduchatea
Copy link
Contributor

Dans un diagramme E/A, il est fréquent d'avoir des associations ternaires impliquant une entité temporelle (date, période).

Par exemple, une réservation entre une cliente, un hôtel à une date donnée :

Hotels : idH, nomH, adresseH, catH, nbChambres
Dates : dateR
Clientes : idC, nomC, prenomC, adresseC, telC
Réservations, 0n Clientes, 0n Hotels, 0n Dates : dureeR

Lors de la trduction en relationnel, il est probable que l'entité Dates ne devienne pas une relation. Mocodo le prend en compte et commente la relation Dates (dans le code Latex) :

  \textsc{Clientes} & (\prim{idC}, \attr{nomC}, \attr{prenomC}, \attr{adresseC}, \attr{telC})\\
% \textsc{Dates} & (\prim{dateR})\\
  \textsc{Hotels} & (\prim{idH}, \attr{nomH}, \attr{adresseH}, \attr{catH}, \attr{nbChambres}, \foreign{idS})\\
  \textsc{Réservations} & (\foreign{\prim{idC}}, \foreign{\prim{idH}}, \foreign{\prim{dateR}}, \attr{dureeR})\\

Par contre, dans la relation Réservations, l'attribut dateR est à la fois clé primaire et clé étrangère (aussi bien dans la sortie Latex que celle en texte brut). Comme la relation Dates n'est pas créée, je pense que cet attribut devrait être simplement clé primaire, comme ceci :

  \textsc{Clientes} & (\prim{idC}, \attr{nomC}, \attr{prenomC}, \attr{adresseC}, \attr{telC})\\
% \textsc{Dates} & (\prim{dateR})\\
  \textsc{Hotels} & (\prim{idH}, \attr{nomH}, \attr{adresseH}, \attr{catH}, \attr{nbChambres}, \foreign{idS})\\
  \textsc{Réservations} & (\foreign{\prim{idC}}, \foreign{\prim{idH}}, prim{dateR}, \attr{dureeR})\\

Dans la sortie ddiagramme relationnel, la contrainte de clé étrangère semble être désactivée :

:
Réservations: #idC->Clientes->idC, _#idH->Hotels->idH, _dateR, dureeR
:
Hotels: idH, nomH, adresseH, catH, nbChambres
:

:
Clientes: idC, nomC, prenomC, adresseC, telC
:::

Peut-on uniformiser les sorties, en choisissant idéalement de supprimer la contrainte de clé étrangère vers des entités non créées ?

@laowantong
Copy link
Owner

Oui, bonne idée. Je pense que ça devrait être faisable sans code en modifiant seulement les fichiers de spécification présents dans le dossier relation_templates. Le format est expliqué dans la doc je crois. Si vous vous sentez capable de le faire, une PR est bienvenue. Sinon, je m'en occuperai la prochaine fois que j'aurai un peu de temps pour Mocodo.

@fduchatea
Copy link
Contributor Author

J'ai regardé/testé et ça devrait le faire avec les gabarits (et ça fait réviser les regexp 😉 ).
Donc ok pour m'en occuper, au moins pour la sortie Latex et texte.

@laowantong
Copy link
Owner

En y réfléchissant, je suis quand même partagé. Prenez l'exemple donné dans le README. Mocodo génère et commente les tables correspondant à DATE et à MATIÈRE. Actuellement, si je veux effectivement supprimer DATE, mais garder MATIÈRE, je dois faire les retouches suivantes :

  • Décommenter MATIÈRE.
  • Supprimer le # de #date.

Si Mocodo supprimait systématiquement les # supprimables, je devrais faire les retouches suivantes :

  • Décommenter MATIÈRE.
  • Ajouter un # à matière.

L'avantage ne me saute pas aux yeux. Il est vrai que dans ce cas, cela uniformiserait les traitements par rapport au diagramme relationnel, point que vous soulevez.

Si vous voulez restreindre le traitement suggéré aux seules entités DATE, cela introduit un cas particulier. Est-ce vraiment désirable ? Je pose la question, mais n'ai pas d'avis tranché.

@fduchatea
Copy link
Contributor Author

Je suis d'accord qu'on peut vouloir conserver certaines entités avec une seule propriété, comme MATIERE.
En général, il est recommandé de ne pas utiliser comme clé primaire un attribut de type chaine de caractères et dont les valeurs peuvent évoluer (conceptuellement, on peut laisser un tel attribut dans le MCD et modifier la clé primaire quand on traduit en Relationnel, mais quand on utilise un outil de modélisation, pas trop le choix de prévoir ça dès le MCD).
Donc j'ai tendance à définir MATIERES(idM, nom), et elle n'est donc commentée en Relationnel.

Dans la même idée, un autre argument contre concerne les entités à plusieurs propriétés qui sont destinées à être supprimées. Par exemple :

PERIODES: dateDébut, dateFin
RESERVATIONS: idX, idY, dateDébut, dateFin

La relation PERIODES ne devrait pas être créée. Mais difficile de détecter ce cas (et ceux avec N propriétés - bien qu'assez rare), et du coup l'intérêt est limité (hormis l'uniformisation des sorties)...

Dans les avantages, on a une sortie Latex ou SQL propre (si on considère le cas DATE qui reste le cas le plus fréquent), même si on génère à nouveau (ajout d'un attribut, changement de couleur, test pour un meilleur arrangement, etc.), ce qui m'arrive assez souvent.

Une solution serait de proposer les 2 gabarits, mais pour éviter la redondance de code, il faudrait pouvoir définir un "gabarit parent" (idée que je vais détailler dans une autre issue pour ne pas mélanger).
Je pense continuer à mettre à jour le gabarit Latex - que je pourrai toujours utiliser personnellement - et on en rediscute.

@laowantong
Copy link
Owner

laowantong commented Nov 23, 2022

Oui, très juste. PÉRIODE peut être supprimée parce qu'elle se trouve réduite à sa clé primaire, laquelle est composite et non formée de clés étrangères. Je ne sais plus quel critère j'ai utilisé pour la mise en commentaire, il faudrait que je regarde le code : si c'est « table réduite à une seule colonne », ça ne couvre pas ces cas.

Pour MATIÈRE, j'ai quand même une petite réticence sur votre modélisation. Certes, on recommande de prendre comme clés des attributs artificiels (typiquement aléatoires), en tout cas non liés aux données-métiers. Mais identifier MATIÈRE par le nom de la matière peut avoir un intérêt au moment de la saisie : le SGBD peut ouvrir un menu pop up permettant de choisir la matière dans une liste déroulante, constituée des valeurs des clés primaires dans la table MATIÈRE.

En fait, pour en revenir à Mocodo, peut-être la meilleure solution consisterait-elle à étendre la syntaxe de façon à pouvoir préciser le traitement souhaité dès la définition du MCD. Après tout, on peut déjà faire ce genre de choses en précisant sur certaines pattes quel suffixe sera ajouté à l'attribut migrant pour rétablir la sémantique d'une association disparue (p. ex., [mère] dans le MCD par défaut de mocodo.net. Ceci pour dire qu'il y a déjà un mélange entre les niveaux conceptuels et relationnels dans les « MCD » de Mocodo. Si on opte pour cette solution, il faut imaginer une syntaxe non intrusive et qui ne crée pas de problème de rétro-compatibilité.

La solution d'une duplication des gabarits, avec éventuellement héritage, est également possible, en effet.

Je ne pense avoir le temps de me replonger dans le code avant mi-décembre, cependant.

@laowantong
Copy link
Owner

Réflexion faite, je penche vers une extension de la syntaxe du MCD, p. ex., les trois dernières lignes de l'exemple du README deviendraient :

Date: Date
+Matière: Libellé matière
Enseigner, 11 Prof, 1N Matière

Le « + » signifierait : forcer la conservation de cette table lors du passage au relationnel. Par défaut, les tables réduites à une clé primaire n'incluant aucune clé étrangère seraient supprimées, ainsi que leur # dans les tables où elles sont étrangères.

@fduchatea
Copy link
Contributor Author

Pour la mise en commentaire, le gabarit latex.json ne commente que les tables avec un seul attribut. Mais vu la définition du search, je me demande comment c'est possible (le '.' matche n'importe quel caractère sauf retour ligne, et le '+' étant greedy, ça devrait matcher toutes les relations ?)

  "transform_single_column_relation": [
    {
      "search": "  (.+)",
      "replace": "% \\1"
    }

identifier MATIÈRE par le nom de la matière peut avoir un intérêt au moment de la saisie : le SGBD peut ouvrir un menu pop up

J'avoue ne pas souvent saisir de données via l'interface du SGBD. Mais c'est plutôt un problème technique : dans l'interface, on pourrait détecter que l'attribut référencé pointe vers une clé primaire (auto-incrémentée) et afficher en complément dans la liste la valeur d'un attribut unique de cette table pour permettre un choix pertinent (dans un monde idéal avec des contraintes définies).

Ok pour l'extension du MCD.
Pour être complet (et prendre en compte l'exemple PERIODES qui doit disparaitre), il faudrait un symbole pour les tables non conservées.
Du coup, je me demande si c'est pas trop complexe d'avoir les '+' et un symbole '-'. Peut-être se contenter d'un symbole '-' uniquement (et par défaut, ne rien supprimer lors de la transformation) ?

@laowantong
Copy link
Owner

OK, je n'avais pas regardé. Si c'est transform_single_column_relation, ça signifie que je n'avais pas envisagé les autres cas, et il faudra probablement changer ça dans le code.

Je pense que cette regex (en tout cas) est relancée sur chaque table, donc pas de débordement possible.

À voir pour le reste.

@fduchatea
Copy link
Contributor Author

Je n'avais pas fait attention au nom de la propriété. J'imagine que c'est au niveau de l'algo qu'on applique cette transformation uniquement aux relations à un seul attribut.

laowantong added a commit that referenced this issue Dec 10, 2022
@laowantong laowantong changed the title Traduction des Dates en relationnel Mécanisme de suppression des tables indépendantes réduites à leur clé primaire Dec 10, 2022
@laowantong
Copy link
Owner

J'ai une solution qui semble fonctionner.

  • Je ne gère plus la suppression des tables au niveau des gabarits. Cela évite des acrobaties avec les expressions régulières pour « naturaliser » les clés étrangères concernées.
  • Les tables en question ne sont plus commentées, mais supprimées.
  • Si on veut empêcher la suppression, on préfixe d'un « + » les entités à préserver.

laowantong added a commit that referenced this issue Dec 11, 2022
laowantong added a commit that referenced this issue Dec 11, 2022
laowantong added a commit that referenced this issue Dec 12, 2022
fix #66
laowantong added a commit that referenced this issue Dec 12, 2022
@fduchatea
Copy link
Contributor Author

Ok pour la solution avant le traitement par les gabarits. Ca a en plus l'avantage de ne pas devoir écrire les transformations dans chaque gabarit.
J'avais écrit les transformations pour le gabarit Latex et c'est vrai que ce n'est pas forcément très maintenable :

  "transform_relational_schema": [
    {
	  "comment": "Detect and delete foreign key constraints for commented single-column relations (when placed before the constrained relation)",
      "search": "(?sm)(<SINGLE_RELATION_TO_BE_COMMENTED>(.+?)</SINGLE_RELATION_TO_BE_COMMENTED>)(.+)\\\\foreign.(.+)<CONSTRAINT_MAY_BE_DELETED>\\2</CONSTRAINT_MAY_BE_DELETED>.",
      "replace": "\\2\\3\\4",
      "iterated": true
    },
    {
	  "comment": "Detect and delete foreign key constraints for commented single-column relations (when placed after the constrained relation)",
	  "comment": ".(.+)(<SINGLE_RELATION_TO_BE_COMMENTED>\\3</SINGLE_RELATION_TO_BE_COMMENTED>)",
      "search": "(?sm)(.+)\\\\foreign.(.+?)<CONSTRAINT_MAY_BE_DELETED>(.+?)</CONSTRAINT_MAY_BE_DELETED>.(.+)(<SINGLE_RELATION_TO_BE_COMMENTED>\\3</SINGLE_RELATION_TO_BE_COMMENTED>)(.+)",
      "replace": "\\1\\2\\4\\5\\6",
      "iterated": true
    }, ...

Je testerai prochainement cette dernière version (après la rédaction des sujets d'examen).

@laowantong
Copy link
Owner

laowantong commented Dec 13, 2022

Documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants