[Merise] Association réflective
Dernière réponse : dans Programmation
Version courte :
Comment modéliser un menu de site web avec une profondeur d'arborescence indéterminée, chaque menu ne pouvant pas avoir le meme père ET la meme position en même temps ?
-------------------
version longue :
Je bloque sur un cas qui me parait classique.
J'ai un menu principal composé de sous-menus, eux memes peut etre composés de sous-menus.
Il y a donc un rapport hiérarchique (menu parent), chaque menu ayant une position unique dans ce menu parent.
J'en arrive à l'association réflexive suivant
Menu [menu_id, menu_label, menu_pos, menu_parent ]
card(0,n) // un menu à 0 ou plusieurs sous-menus
enfante
card(0,1) // un menu à 0 ou 1 parent
Menu [menu_id, menu_label, menu_pos, menu_parent ](duplicata pour mieux voir)
ce qui me donne
Menu [menu_id, menu_label, menu_pos, menu_parent ]
où menu_id est clef primaire auto increment.
Le problème[/color] c'est que dans ce cas, on peut obtenir un menu ayant le meme parent et situé à la meme position sur celui-ci.
Je suppose que je dois obtenir une clef primaire composée de menu_parent et menu_pos avec menu_pos en auto increment.
J'en déduis que je dois avoir une association (0,n) (0,n) pour celà.
A ce stade, je suis un peu perdu. Si quelqu'un sait m'ouvrir la voie :hug:
Comment modéliser un menu de site web avec une profondeur d'arborescence indéterminée, chaque menu ne pouvant pas avoir le meme père ET la meme position en même temps ?
-------------------
version longue :
Je bloque sur un cas qui me parait classique.
J'ai un menu principal composé de sous-menus, eux memes peut etre composés de sous-menus.
Il y a donc un rapport hiérarchique (menu parent), chaque menu ayant une position unique dans ce menu parent.
J'en arrive à l'association réflexive suivant
Menu [menu_id, menu_label, menu_pos, menu_parent ]
card(0,n) // un menu à 0 ou plusieurs sous-menus
enfante
card(0,1) // un menu à 0 ou 1 parent
Menu [menu_id, menu_label, menu_pos, menu_parent ](duplicata pour mieux voir)
ce qui me donne
Menu [menu_id, menu_label, menu_pos, menu_parent ]
où menu_id est clef primaire auto increment.
Le problème[/color] c'est que dans ce cas, on peut obtenir un menu ayant le meme parent et situé à la meme position sur celui-ci.
Je suppose que je dois obtenir une clef primaire composée de menu_parent et menu_pos avec menu_pos en auto increment.
J'en déduis que je dois avoir une association (0,n) (0,n) pour celà.
A ce stade, je suis un peu perdu. Si quelqu'un sait m'ouvrir la voie :hug:
Autres pages sur : merise association reflective
Lassé par la pub ? Créez un compte
Mon merise est un peu loin, je vais donc essayer de te répondre en dehors de la syntaxe merise, mais plus base de données.
Puisqu'un menu a un seul parent et une seule position, qu'un autre menu peut soit :
- avoir le même parent, mais pas la même position
- avoir la même position, mais pas le même parent
Comme tu l'indiques, tu peux donc utiliser le couple menu_pos et menu parent comme clé (plus besoin de menu_id).
Ce menu_pos, que représente-il exactement ? La position "physique" dans le sous menu ? Si oui, tu ne peux utiliser d'auto-incrément (2 menus peuvent avoir la même pos).
Sinon tu as aussi la possibilité d'une table intermédiaire, qui contient la clé de menu (menu_id du parent), la clé de menu (menu_id de l'enfant) et un champ pos. Soit t_menu_intermediaire le nom de la table
menu [menu_id, ... plus de pos, ni parent]
card(0,n)
enfante
card(1,1)
t_menu_intermediaire [menu_id_parent,menu_id_enfant,menu_pos]
card(1,1)
correspond_a
card(1,1)
menu [menu_id, ... plus de pos, ni parent]
Je ne suis pas sur d'avoir répondu à ta question, car je ne la saisis pas vraiment.
Puisqu'un menu a un seul parent et une seule position, qu'un autre menu peut soit :
- avoir le même parent, mais pas la même position
- avoir la même position, mais pas le même parent
Comme tu l'indiques, tu peux donc utiliser le couple menu_pos et menu parent comme clé (plus besoin de menu_id).
Ce menu_pos, que représente-il exactement ? La position "physique" dans le sous menu ? Si oui, tu ne peux utiliser d'auto-incrément (2 menus peuvent avoir la même pos).
Sinon tu as aussi la possibilité d'une table intermédiaire, qui contient la clé de menu (menu_id du parent), la clé de menu (menu_id de l'enfant) et un champ pos. Soit t_menu_intermediaire le nom de la table
menu [menu_id, ... plus de pos, ni parent]
card(0,n)
enfante
card(1,1)
t_menu_intermediaire [menu_id_parent,menu_id_enfant,menu_pos]
card(1,1)
correspond_a
card(1,1)
menu [menu_id, ... plus de pos, ni parent]
Je ne suis pas sur d'avoir répondu à ta question, car je ne la saisis pas vraiment.
le résultat que j'obtiens qui me semble bon, c'est deux tables :
rapport_pere_fils
id_du_pere = #id_menu , pos_du_fils
#id_du_fils
menu
id_menu = #id_du_fils
libellé_du_menu
sauf que je n'arrive pas à voir quel mcd peut déboucher là-dessus.
rapport_pere_fils m'évoque une association (*,n) (*,n) pour sa clef primaire sur deux colonnes
d'un autre coté, ces deux champs n'apparaissent pas en clef primaire dans d'autres tables, et le fait qu'il y ait une clef étrangère m'évoque plus une table (*,1) associée à une table (*,n)
edit: cool une réponse, je n'y croyais plus.
rapport_pere_fils
id_du_pere = #id_menu , pos_du_fils
#id_du_fils
menu
id_menu = #id_du_fils
libellé_du_menu
sauf que je n'arrive pas à voir quel mcd peut déboucher là-dessus.
rapport_pere_fils m'évoque une association (*,n) (*,n) pour sa clef primaire sur deux colonnes
d'un autre coté, ces deux champs n'apparaissent pas en clef primaire dans d'autres tables, et le fait qu'il y ait une clef étrangère m'évoque plus une table (*,1) associée à une table (*,n)
edit: cool une réponse, je n'y croyais plus.
en fait, mon probleme, c'est qu'il est interdit de mettre un couple d'identifiant dans le mcd (enfin, il me semble).
les couples d'identifiants, la clef primaire sur deux colonnes est obtenu apres conversion du mcd en mld.
J'utilise le logiciel AnalyseSI qui converti un MCD en MLD. Le MLD c'est un dessin qui correspond à la structure des tables.
AnalyseSI me génère alors automatiquement les requêtes de création de la base. Comme c'est pas compatible mysql pour le moment, j'ai fait un script php qui traduit les requetes access d'analyseSI en requetes MySQL.
Bref l'interet est de pouvoir faire un bon modèle qui entraine une création de table que je n'ai plus à retoucher. si je dois modifier les tables, je modifie le MCD qui va lui modifier les tables. j'ai toujours un plan clair de mes bases et des relations entre les tables.
les couples d'identifiants, la clef primaire sur deux colonnes est obtenu apres conversion du mcd en mld.
J'utilise le logiciel AnalyseSI qui converti un MCD en MLD. Le MLD c'est un dessin qui correspond à la structure des tables.
AnalyseSI me génère alors automatiquement les requêtes de création de la base. Comme c'est pas compatible mysql pour le moment, j'ai fait un script php qui traduit les requetes access d'analyseSI en requetes MySQL.
Bref l'interet est de pouvoir faire un bon modèle qui entraine une création de table que je n'ai plus à retoucher. si je dois modifier les tables, je modifie le MCD qui va lui modifier les tables. j'ai toujours un plan clair de mes bases et des relations entre les tables.
3 tables qui n'en font que deux, puisque père et fils sont la même table.
Mais si tu ne peux faire qu'une liaison dans ton mcd, alors la table intermédiaire est la meilleure solution.
D'ailleurs, en base de données, tu n'aurais pas trop le choix. Les tables intermédiaires sont la plupart du temps obligatoires pour représenter une relation (*,n)<->(*,n) (avec access ou mysql, je ne connais pas les bd du style postgresql ou oracle).
Donc, toujours essayé de transformer
(*,n)<->(*,n)
en
(*,n)<->(*,1)-(*,1)<->(*,n)
Mais si tu ne peux faire qu'une liaison dans ton mcd, alors la table intermédiaire est la meilleure solution.
D'ailleurs, en base de données, tu n'aurais pas trop le choix. Les tables intermédiaires sont la plupart du temps obligatoires pour représenter une relation (*,n)<->(*,n) (avec access ou mysql, je ne connais pas les bd du style postgresql ou oracle).
Donc, toujours essayé de transformer
(*,n)<->(*,n)
en
(*,n)<->(*,1)-(*,1)<->(*,n)
je m'aperçois qu'on peut poser le probleme simplement en
un parent génère 0 ou plusieurs positions d'enfant
une position d'enfant est générée par un ou plusieurs parents
on a donc
parent
idparent
(0,n) |
génère
attr: libéllé_généré
(1,n) |
position
idposition
ce qui en terme de bdd se traduit par
parent
idparent
génère
idparent, idposition
libéllé_généré
position
idposition
parent et position etant quelque peu inutiles, il nous reste une table issue de l'association
génère
gen_idparent, gen_idpos
gen_label
y a qu'un truc qui me gène, c'est que position, pour moi c'est un lieu, un emplacement, pas un objet.
un parent génère 0 ou plusieurs positions d'enfant
une position d'enfant est générée par un ou plusieurs parents
on a donc
parent
idparent
(0,n) |
génère
attr: libéllé_généré
(1,n) |
position
idposition
ce qui en terme de bdd se traduit par
parent
idparent
génère
idparent, idposition
libéllé_généré
position
idposition
parent et position etant quelque peu inutiles, il nous reste une table issue de l'association
génère
gen_idparent, gen_idpos
gen_label
y a qu'un truc qui me gène, c'est que position, pour moi c'est un lieu, un emplacement, pas un objet.
Lassé par la pub ? Créez un compte