IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Schéma Discussion :

Modélisation catégories, sous-catégories, rubriques


Sujet :

Schéma

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut Modélisation catégories, sous-catégories, rubriques
    Bonjour,

    Je souhaite modéliser une application visant à tester le niveau d’orthographe d’un utilisateur en lui soumettant une série de phrases (une seule phrase à la fois) pouvant comporter de 0 à 1 erreur.

    Les phrases proposées se rattachent à des parties, sous-parties, rubriques et règles selon la structure suivante :

    une phrase se rattache à une et une seule règle d’orthographe ; laquelle règle peut appartenir à une et une seule rubrique ; laquelle rubrique, si elle existe, peut appartenir à une et une seule sous-partie ; laquelle sous-partie, si elle existe, appartient à une et une seule partie.

    À rebours, la structure est la suivante : une partie contient aucune ou plusieurs sous-parties ; une sous-partie contient aucune ou plusieurs rubriques ; une rubrique contient une ou plusieurs règles ; une règle concerne plusieurs phrases.

    J'ai élaboré le MCD correspondant :
    Nom : mcd_phrases.jpg
Affichages : 2176
Taille : 88,1 Ko

    Ma modélisation vous paraît-elle cohérente ? L'idée au final est d'être en mesure de détermiser à quelle règle une phrase se rattache, à quelle rubrique et à quelle sous-partie elle appartient éventuellement et à quelle partie elle se rattache. Merci.

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour almoha,

    A 1re vue, votre MCD paraît correct :

    Une phrase détermine une règle, et par transitivité, une rubrique, une sous-partie, une partie : on sait donc à quelle partie appartient une phrase.


    Cela dit, la patte connectant REGLE et APPARTENIR est porteuse non pas d’une cardinalité 1,1, mais 0,1, même chose pour la patte connectant RUBRIQUE et l’autre association APPARTENIR. Ceci est-il délibéré ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Merci de votre avis fsmrel. Pour répondre à votre interrogation, les cardinalités choisies l'ont été de façon délibérée car dans mon postulat :

    - une règle n'est pas forcément englobée dans une rubrique;
    - une rubrique n'est pas forcément englobée dans une sous-partie

    Voici un exemple de données balayant les différents cas de figure :

    Nom : exemple_données.jpg
Affichages : 1753
Taille : 56,7 Ko

    Le MCD vous paraît-il toujours correct ? Merci encore.

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Votre exemple est bien parlant et vaut mieux qu’un long discours...

    J’observe que la règle « est-ce que » ne fait pas référence à une rubrique : d’accord, mais elle fait référence à une sous-partie : ceci devrait être pris en compte dans le MCD.

    Même observation pour la règle « a ; à », faisant directement référence à une partie.

    Le MCD doit donc être complété, et l’on subodore que les contraintes d’exclusion et/ou la spécialisation des entités-types risquent de montrer le bout de leur nez...


    N.B. Dans le MCD, le terme « parties » représente le nom d’une entité-type : l’emploi du singulier s’impose pour ce nom (à l’image de ce que vous avez fait dans votre exemple).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Bonsoir,

    Il faut donc que j'intègre l'héritage dans mon MCD ? L'entité père serait l'entité "partie" et les entités filles seraient les entités "sous_partie", "rubrique" et "règle" ?
    J'avoue ne pas trop savoir comment procéder pour compléter le MCD comme vous le suggérez... Dois-je rajouter des relations ? Entre l'entité "regle " et les entités "sous-partie" et "partie" ou autres ?
    Pouvez-vous m'aider à y voir plus clair ? Merci.

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    Citation Envoyé par almoha
    Il faut donc que j'intègre l'héritage dans mon MCD ?
    Oui, mais on va surtout parler de généralisation/spécialisation.



    Citation Envoyé par almoha
    L'entité père serait l'entité "partie" et les entités filles seraient les entités "sous-partie", "rubrique" et "règle" ?
    J’espère que vous ne m’en voudrez pas de commencer par préciser le sens de certains termes...

    Faisons la différence entre entité et entité-type (type d’entité) : une entité est une instance, une valeur d’entité-type. On retrouve le distinguo entre la proposition et le prédicat (lequel est une fonction vérifonctionnelle, c'est-à-dire dont l’invocation fournit une valeur de vérité, à savoir vrai ou faux) :

    La proposition « Le soleil est une étoile » est vraie, et rend vrai le prédicat « x est une étoile », tandis que la proposition « La terre est une étoile » rend faux le même prédicat.

    Dans le même ordre d’idée, PARTIE est une entité-type (type d’entité), tandis que « Formes et accords du verbe » peut être qualifié d’entité.

    Pour répondre à votre question, PARTIE, SOUS_PARTIE, RUBRIQUE et REGLE sont des entités-types dont certaines présentent la particularité d’avoir pour parente telle ou telle autre entité-type, ce qui est bien embêtant dans le contexte de la modélisation...

    Ainsi, REGLE est fille soit de PARTIE, de SOUS_PARTIE, ou de RUBRIQUE. Pour traiter ce problème, on va mettre en œuvre la technique de généralisation/spécialisation :

    REGLE est fille d’une nouvelle entité-type, appelons-la E (je suis en mal d’imagination pour lui trouver un nom...) qui est la généralisation de PARTIE, SOUS_PARTIE et RUBRIQUE :





    Et l’entité-type E (considérée alors comme surtype) est spécialisée en PARTIE, SOUS_PARTIE et RUBRIQUE (considérées comme sous-types de E).

    Le cercle contenant le symbole « XT » symbolise la relation entre le surtype et les sous-types. La lettre X du symbole « XT » lui-même signifie que les sous-types sont exclusifs (une partie ne peut pas être simultanément une sous-partie ou une rubrique, etc.), et la lettre T signifie qu’une instance de E est illégale si elle n’est pas associée à une instance d’un des sous-types (contrainte de totalité).

    L’association entre PARTIE et SOUS_PARTIE est conservée. L’association entre RUBRIQUE et PARTIE ou SOUS_PARTIE n’est pas préservée, il faut donc compléter le MCD. Une rubrique pouvant être associée à une partie ou une sous-partie, les entités-types PARTIE et SOUS_PARTIE peuvent être l’objet d’une généralisation (au moyen d’un surtype que j’appelle F, toujours par manque d’imagination...) : l’entité-type F et à la fois sous-type (en relation ave E) et surtype (en relation avec PARTIE et SOUS_PARTIE). Via F, une rubrique est composant d’au moins et au plus une instance de F, c'est-à-dire soit de PARTIE soit de SOUS_PARTIE :






    Bon d’accord, ça paraît être un drôle de meccano que celui-là, mais j’espère vous avoir donné une piste de réflexion...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #7
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut une alternative : la réflexivité
    Bonsoir almoha,


    Si le meccano que je vous ai proposé vous paraît un peu compliqué, il y a une solution alternative, basée sur la réflexivité :

    — Un élément est d’un certain type : phrase, règle, rubrique, sous-partie, partie.

    — Un élément peut être composé de zéro à plusieurs éléments.

    — Un élément peut être composant d’un autre élément.


    MCD




    MLD dérivé






    En partant de votre exemple :

    Table TYPE_ELEMENT

    
    TypeElementId    TypeElementlibelle
                1    Partie
                2    Sous-partie
                3    Rubrique
                4    Règle
                5    Phrase
    
    
    Table ELEMENT

    
    ElementId    TypeElementId    ElementTexte
            1                1    Formes et accords du verbe
            2                1    Formes et accords du nom, de l’adjectif du verbe
            3                1    Orthographe lexicale, signes graphiques et syntaxe
            4                1    Ces mots que l’on confond...
            5                2    Le verbe : ses formes
            6                2    Syntaxe
            7                3    L’infinitif
            8                3    Les noms : leur féminin, leur pluriel
            9                4    Une forme invariable
           10                4    Le pluriel des noms : cas généraux
           11                4    est-ce que
           12                4    a ; à
           13                5    phrases 
           14                6    autres phrases 
           15                6    autres phrases 
           16                6    autres phrases 
    
    
    Table COMPOSITION

    
    ElementComposantId    ElementComposeId
                     5                   1
                     6                   3
                     7                   5
                     8                   2
                     9                   7
                    10                   8
                    11                   6
                    12                   4
                    13                   9
                    14                  10
                    15                  11
                    16                  12
    
    
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  8. #8
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Effectivement la solution mettant en œuvre la réflexivité me parle a priori davantage. Je suis donc parti du canevas proposé pour essayer de compléter mon MCD.

    Pour rappel, je souhaite modéliser une application visant à tester le niveau d’orthographe d’un utilisateur en lui soumettant une série de phrases (une seule phrase à la fois) d’une difficulté variable (association ETRE dans le MCD) pouvant comporter de 0 à 1 erreur.
    L’utilisateur peut cibler les règles d’orthographe qu’il entend voir aborder, ce en choisissant le thème des phrases qui seront proposées selon un spectre plus ou moins large : partie, sous-partie, rubrique ou règle (entité ELEMENT dans le MCD).
    S’il estime que la phrase est correcte, ce dernier est invité à cliquer sur un bouton prévu à cet effet ; s’il repère au contraire un mot fautif, il doit cliquer dessus.

    Je prends un exemple, soit la phrase incorrecte suivante :

    Il et fort et agile.

    Si l’utilisateur clique sur le 2e mot de la phrase (« et »), sa réponse est déclarée bonne ; s’il clique sur un mot dont la position est différente de 2 ou s’il clique sur le bouton « pas d’erreur », sa réponse est déclarée mauvaise.
    Au travers de cet exemple, nous voyons que le critère lié à la position du mot dans la phrase permet de déterminer si la réponse apportée par l’utilisateur est bonne (association COMPORTER dans le MCD).

    Autre exemple, soit la phrase correcte suivante :

    Elle est grande.

    Si l’utilisateur clique sur le bouton « pas d’erreur », sa réponse est déclarée bonne ; s’il clique sur un mot, quel qu’il soit, sa réponse est déclarée mauvaise.

    Après que l’utilisateur a validé son choix, l’application sera capable :

    — d’indiquer si la réponse fournie est correcte ou non ;
    — d’afficher la phrase correctement orthographiée (association CORRESPONDRE dans le MCD) ;
    — d’afficher la règle d’orthographe à laquelle se rattache la phrase.

    Ci-dessous, le MCD complété qui découle de ce qui précède :

    Nom : mcd_phrases_2.jpg
Affichages : 2225
Taille : 102,7 Ko

    J’ai conscience de sa probable perfectibilité et en appelle à votre indulgence... Qu’en pensez-vous ? Merci d’avance pour votre aide.

  9. #9
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    Votre MCD n’est pas mal, mais j’ai bien sûr ^^ quelques remarques à faire :

    1) La patte connectant l’entité-type MOT_ERRONE et l’association COMPORTER est porteuse d’une cardinalité 0,1 (coquille de votre part ?), c'est-à-dire qu’il y aurait des mots erronés isolés inutilisés, donc inutiles : remplacer la cardinalité 0,1 par une cardinalité 1,1. Par ailleurs, si une phrase ne comporte au plus qu’un seul mot erroné, repéré par sa position dans la phrase, on peut faire l’économie de l’entité-type MOT_ERRONE et faire figurer l’attribut Position dans l’entité-type ELEMENT : si une phrase ne comporte aucun mot erroné, l’attribut Position prendrait alors la valeur 0 (ou autre valeur spéciale à votre convenance). Par contre il faudrait revoir ce montage au cas où, à l’avenir, vous mettriez en place un système dans lequel une phrase pourrait comporter plus d’un mot erroné.

    2) L’association REPONDRE permet de savoir que l’utilisateur Raoul a fourni une réponse pour la phrase « Il et fort et agile », mais ça s’arrête là, on ne sait pas s’il a choisi la bonne ou mauvaise réponse...

    3) Les cardinalités 0,1 portées par les pattes connectant l’entité-type ELEMENT et les associations COMPORTER, ETRE et COMPOSITION donneront lieu au stade SQL à la pollution de la table ELEMENT par le bonhomme Null, lequel y posera tranquillement ses pièges. Je vous renvoie à son sujet au message « Null : logique ternaire vs logique binaire ».

    Dans mon précédent message, j’ai proposé un MLD selon lequel il n’est pas possible au bonhomme pervers de se manifester : la table MODELISATION est là pour ça (en remplacement d’une auto-référence de la table ELEMENT).

    Du fait des attributs supplémentaires DifficulteId (clé étrangère par rapport à la clé primaire de la table DIFFICULTE), et Position (cf. ci-dessus, le point 1), la table ELEMENT devient la suivante :

    
    ElementId    TypeElementId    DifficulteId    Position    ElementTexte
            1                1    Null            Null        Formes et accords du verbe
            2                1    Null            Null        Formes et accords du nom, de l’adjectif du verbe
            3                1    Null            Null        Orthographe lexicale, signes graphiques et syntaxe
            4                1    Null            Null        Ces mots que l’on confond...
            5                2    Null            Null        Le verbe : ses formes
            6                2    Null            Null        Syntaxe
            7                3    Null            Null        L’infinitif
            8                3    Null            Null        Les noms : leur féminin, leur pluriel
            9                4    Null            Null        Une forme invariable
           10                4    Null            Null        Le pluriel des noms : cas généraux
           11                4    Null            Null        est-ce que
           12                4    Null            Null        a ; à
           13                5    Null            Null        phrases 
           14                6               1           2    Il et fort et agile 
           15                6               1           0    Elle est grande 
           16                6               1           5    Le petit chat est morts 
           17                6               4           0    Il aime le cuissot de chevreuil 
           18                6               4           5    Il aime aussi le cuissot de veau
           19                6               3           0    C’est une imbécillité
           20                6               2           5    Il a un petit soucis
    
    
    Ça n’est guère acceptable... Pour améliorer la chose, je propose que l’on fasse apparaître l’entité-type PHRASE dans le MCD :





    D’où le MLD :






    En instanciant (aux coquilles et fantaisies près de ma part...) :

    Table TYPE_ELEMENT (débarrassée de l’élément « Phrase » devenu sans emploi) :

    
    TypeElementId    TypeElementlibelle
                1    Partie
                2    Sous-partie
                3    Rubrique
                4    Règle
    
    
    Table ELEMENT (débarrassée des phrases) :

    
    ElementId    TypeElementId    ElementTexte
            1                1    Formes et accords du verbe
            2                1    Formes et accords du nom, de l’adjectif du verbe
            3                1    Orthographe lexicale, signes graphiques et syntaxe
            4                1    Ces mots que l’on confond...
            5                2    Le verbe : ses formes
            6                2    Syntaxe
            7                3    L’infinitif
            8                3    Les noms : leur féminin, leur pluriel
            9                4    Une forme invariable
           10                4    Le pluriel des noms : cas généraux
           11                4    est-ce que
           12                4    a ; à
           13                4    confusions
    
    

    Table COMPOSITION (dans laquelle le ménage a aussi été fait) :

    
    ElementComposantId    ElementComposeId
                     5                   1
                     6                   3
                     7                   5
                     8                   2
                     9                   7
                    10                   8
                    11                   6
                    12                   4
                    13                   4
    
    

    Table DIFFICULTE

    
    DifficulteId    DifficulteTexte
               1    Facile 
               2    Assez facile
               3    Piège classique
               4    Niveau Mérimée
    
    

    Table PHRASE

    
    PhraseId    ElementId    DifficulteId    Position    Texte
           1           13               1           2    Il et fort et agile 
           2           13               1           0    Elle est grande 
           3           10               1           5    Le petit chat est morts 
           4           13               4           0    Il aime le cuissot de chevreuil
           5           13               4           5    Il aime aussi le cuissot de veau
           6           13               3           0    C’est une imbécillité
           7           10               2           5    Il a un petit soucis
    
    

    Table CORRIGE

    
    PhraseId    CorrigeTexte
           1    Il est fort et agile 
           3    Le petit chat est mort 
           5    Il aime aussi le cuisseau de veau 
           7    Il a un petit souci
    
    
    A noter que, si dans la table PHRASE l’attribut Position a la valeur 0, alors la clé primaire {PhraseId} de cette table n’a pas à être référencée par une clé étrangère {PhraseId} de la table CORRIGE. Partant, il est possible de définir une contrainte à sous-traiter au SGBD (au fait, quel est le vôtre ?)

    {PhraseId} est clé primaire de la table CORRIGE, mais aussi clé étrangère par rapport à la table PHRASE (en effet, quel intérêt de mettre en œuvre un attribut CorrigeId ?), et pour parvenir à cela j’ai utilisé l’identification relative : avec l’AGL que j’ai utilisé (PowerAMC), la convention est de mettre entre parenthèses la cardinalité 1,1 portée par la patte connectant CORRIGE et CORRESPONDRE. Dans ces conditions, la clé primaire de la table PHRASE fait automatiquement partie de la clé primaire de la table CORRIGE (on parle encore d’héritage).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  10. #10
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Bonjour,

    Merci fsmrel pour votre aide précieuse.

    Je rebondis sur votre commentaire :
    2) L’association REPONDRE permet de savoir que l’utilisateur Raoul a fourni une réponse pour la phrase « Il et fort et agile », mais ça s’arrête là, on ne sait pas s’il a choisi la bonne ou mauvaise réponse...
    Vous avez raison. A ce sujet, la gestion des réponses apportées par l’utilisateur m’apparaît complexe car au final l’application devra être capable de :

    1- comptabiliser, à des fins statistiques, le nombre total de réponses apportées par un utilisateur depuis qu’il utilise l’application en lui indiquant la répartition entre bonnes et mauvaise réponses ;

    2- déterminer si une règle d’orthographe est acquise :

    => une règle est considérée comme « acquise » si l’utilisateur a répondu au moins une fois correctement à toutes les phrases rattachées à ladite règle (10, 15, 20 ou 40 phrases selon les règles).
    => une règle est considérée comme en « cours d’acquisition » si l’utilisateur a répondu au moins une fois correctement à au moins une phrase (mais pas toutes) rattachée à ladite règle.
    => dans les autres cas, une règle est considérée comme « non acquise » : soit l’utilisateur a toujours fourni de mauvaises réponses soit il n’a jamais répondu aux phrases rattachées à ladite règle.

    Ces nouvelles règles de gestion nécessitent-elles de créer une entité-type REGLE (l’élément Règle de l’entité-type ELEMENT disparaissant) ? De plus, il me semble qu’il faut tenir compte du nombre de phrases par règle pour gérer l’acquisition de cette dernière.

    Qu’en pensez-vous ? Merci encore.

    PS : j’utilise MySQL.

  11. #11
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    Citation Envoyé par almoha
    Une règle est considérée comme « acquise » si l’utilisateur a répondu au moins une fois correctement à toutes les phrases rattachées à ladite règle (10, 15, 20 ou 40 phrases selon les règles).
    Autrement dit, il est nécessaire que l’on dispose d’un attribut permettant de définir le seuil d’acquisition pour une règle.

    A cet effet, on peut considérer dans un 1er temps une entité-type REGLE qui soit une spécialisation de l’entité-type ELEMENT, et sur laquelle on connecte l’entité-type PHRASE :


    MCD





    MLD




    Mais dans 2e temps, on peut sortir REGLE de la nomenclature ELEMENT et en faire une entité-type qui ne soit pas une spécialisation d’ELEMENT, et je pense qu’il sera plus simple en l’occurrence d’opérer :


    MCD





    MLD





    Script MySQL de création des tables, correspondant à ce dernier scénario :

    
    CREATE TABLE TYPE_ELEMENT 
    (
            TypeElementId        INT             NOT NULL
          , TypeElementLibelle   VARCHAR(16)     NOT NULL
        , CONSTRAINT TYPE_ELEMENT_PK PRIMARY KEY (TypeElementId)
    ) ;
    
    CREATE TABLE ELEMENT 
    (
            ElementId            INT             NOT NULL
          , TypeElementId        INT             NOT NULL
          , ElementTexte         VARCHAR(64)     NOT NULL
        , CONSTRAINT ELEMENT_PK PRIMARY KEY (ElementId)
        , CONSTRAINT ELEMENT_TYPE_ELEMENT_FK FOREIGN KEY (TypeElementId)
          REFERENCES TYPE_ELEMENT (TypeElementId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE COMPOSITION 
    (
            ElementComposantId       INT             NOT NULL
          , ElementComposeId         INT             NOT NULL
        , CONSTRAINT COMPOSITION_ELEMENT_COMPOSANT_FK FOREIGN KEY (ElementComposantId)
          REFERENCES ELEMENT (ElementId) ON DELETE CASCADE
        , CONSTRAINT COMPOSITION_ELEMENT_COMPOSE_FK FOREIGN KEY (ElementComposeId)
          REFERENCES ELEMENT (ElementId)      
    ) ;
    
    CREATE TABLE REGLE 
    (
            RegleId              INT             NOT NULL
          , ElementId            INT             NOT NULL        
          , RegleTexte           VARCHAR(64)     NOT NULL
          , SeuilAcquisition     INT             NOT NULL
        , CONSTRAINT REGLE_PK PRIMARY KEY (RegleId)
        , CONSTRAINT REGLE_ELEMENT_FK FOREIGN KEY (ElementId)
          REFERENCES ELEMENT (ElementId)
     ) ;
    
    CREATE TABLE DIFFICULTE 
    (
            DifficulteId         INT             NOT NULL
          , DifficulteTexte      VARCHAR(32)     NOT NULL
        , CONSTRAINT DIFFICULTE_PK PRIMARY KEY (DifficulteId)
    ) ;
    
    CREATE TABLE PHRASE 
    (
            PhraseId             INT             NOT NULL
          , RegleId              INT             NOT NULL
          , DifficulteId         INT             NOT NULL
          , Position             INT             NOT NULL
          , Texte                VARCHAR(64)     NOT NULL
        , CONSTRAINT PHRASE_PK PRIMARY KEY (PhraseId)
        , CONSTRAINT PHRASE_REGLE_FK FOREIGN KEY (RegleId)
          REFERENCES REGLE (RegleId)
        , CONSTRAINT PHRASE_DIFFICULTE_FK FOREIGN KEY (DifficulteId)
          REFERENCES DIFFICULTE (DifficulteId)
    ) ;
    
    CREATE TABLE CORRIGE 
    (
            PhraseId             INT             NOT NULL
          , CorrigeTexte         VARCHAR(64)     NOT NULL
        , CONSTRAINT CORRIGE_PK PRIMARY KEY (PhraseId)
        , CONSTRAINT CORRIGE_PHRASE_FK FOREIGN KEY (PhraseId)
          REFERENCES PHRASE (PhraseId) ON DELETE CASCADE
    ) ;
    
    

    Amorce d’un début de jeu d’essai :

    
    INSERT INTO TYPE_ELEMENT (TypeElementId, TypeElementLibelle) VALUES 
        (1, 'Partie'), (2, 'Sous-partie'), (3, 'Rubrique') ;
        
    SELECT * FROM TYPE_ELEMENT ;
    
    INSERT INTO ELEMENT (ElementId, TypeElementId, ElementTexte) VALUES
        (1, 1, 'Formes et accords du verbe')
      , (2, 1, 'Formes et accords du nom, de l''adjectif du verbe')
      , (3, 1, 'Orthographe lexicale, signes graphiques et syntaxe')
      , (4, 1, 'Ces mots que l''on confond')
      , (5, 2, 'Le verbe : ses formes')
      , (6, 2, 'Syntaxe')
      , (7, 3, 'L''infinitif')
      , (8, 3, 'Les noms : leur féminin, leur pluriel') ;
    
    SELECT * FROM ELEMENT ;
    
    INSERT INTO COMPOSITION  (ElementComposantId, ElementComposeId) VALUES
        (5,1), (6, 3), (7, 5), (8, 2) ;
    
    SELECT * FROM COMPOSITION ; 
     
    INSERT INTO DIFFICULTE (DifficulteId, DifficulteTexte) VALUES
        (1, 'Facile'), (2, 'Assez facile'), (3, 'Piège classique'), (4, 'Niveau Mérimée') ;  
     
    SELECT * FROM DIFFICULTE ;
    
    INSERT INTO REGLE (RegleId, ElementId, RegleTexte, SeuilAcquisition) VALUES
        (1, 4, 'Le pluriel des noms : cas généraux', 20)
      , (2, 4, 'est-ce que', 15) 
      , (3, 4, 'a ; à', 10)
      , (4, 4, 'confusions', 30)   
    ;
    
    SELECT * FROM REGLE ; 
    
    INSERT INTO PHRASE (PhraseId, RegleId, DifficulteId, Position, Texte) VALUES
        (1, 4, 1, 2, 'Il et fort et agile')
      , (2, 4, 1, 0, 'Elle est grande')
      , (3, 1, 1, 5, 'Le petit chat est morts')
      , (4 ,4, 4, 0, 'Il aime le cuissot de chevreuil')
      , (5, 4, 4, 5, 'Il aime aussi le cuissot de veau')
      , (6, 4, 3, 0, 'C''est une imbécillité')
      , (7, 1, 2, 5, 'Il a un petit soucis')
    ;
    
    SELECT * FROM PHRASE ;
    
    Etc.
    
    

    Pour se simplifier la vie par la suite, on peut créer une vue permettant de savoir quel est le seuil d’acquisition de la règle pour chaque phrase :

    
    CREATE VIEW PHRASE_SEUIL_ACQUISITION (PhraseId, DifficulteId, Position, Texte, Regle, Seuil) AS
        SELECT x.PhraseId, x.DifficulteId, x.Position, x.Texte, y.RegleTexte, y.SeuilAcquisition
        FROM   PHRASE AS x JOIN REGLE AS y ON x.RegleId = y.RegleId 
    ;
    
    SELECT * FROM PHRASE_SEUIL_ACQUISITION ;
    
    
    =>

    
    PhraseId  DifficulteId  Position  Texte                             Regle                               Seuil
           3             1         5  Le petit chat est morts           Le pluriel des noms : cas généraux     20
           7             2         5  Il a un petit soucis              Le pluriel des noms : cas généraux     20
           1             1         2  Il et fort et agile               confusions                             30
           2             1         0  Elle est grande                   confusions                             30
           4             4         0  Il aime le cuissot de chevreuil   confusions                             30
           5             4         5  Il aime aussi le cuissot de veau  confusions                             30
           6             3         0  C'est une imbécillité             confusions                             30
    
    


    Citation Envoyé par almoha
    Vous avez raison
    Oui... mais que comptez-vous faire ? Par exemple, doter REPONDRE d’un attribut Position comparable à celui de l’entité-type PHRASE ?

    Exemple :


    MCD




    Avec la possibilité que Position prenne la valeur 0, signifiant que l’utilisateur a cliqué sur le bouton « Pas d’erreur ».


    MLD





    Question : l’utilisateur a-t-il le droit de se représenter à l’avenir et repasser la même épreuve ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  12. #12
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Merci de vos conseils judicieux. Ces derniers m’amènent à préciser voire à ajuster mes règles de gestion (désolé pour les redites) :

    1- L’utilisateur choisit une règle d’orthographe à aborder (son choix se fait au travers de l’arborescence partie/sous-partie/rubrique).

    2- L’application affiche successivement toutes les phrases rattachées à cette règle.

    a) Pour chaque phrase, l’utilisateur doit déterminer si elle comporte ou non une erreur (la position du mot cliqué permet de vérifier sa réponse [position 0 si la phrase ne comporte aucun mot erroné])
    b) Après chaque validation de phrase, l’application indiquera à l’utilisateur si la réponse fournie est correcte ou non ; affichera la phrase correctement orthographiée ; affichera la règle d’orthographe à laquelle se rattache la phrase.

    3- Une fois toutes les phrases de la règle en question passées en revue, l’application affichera le nombre de bonnes et mauvaises réponses.

    4- Problématique de l’acquisition d’une règle :

    a) Par défaut une règle a le statut « à acquérir » => ce statut concerne les règles que l’utilisateur n’a pas encore étudiées en répondant aux questions associées.
    b) Le statut passe à l’état « acquis » si l’utilisateur a répondu au moins trois fois correctement à toutes les phrases rattachées à ladite règle (10, 15 , 20 ou 40 phrases selon les règles).
    c) Dès que l’utilisateur commence à étudier une règle dans l’optique de l’acquérir, le statut de la règle passe à l’état intermédiaire « en cours d’acquisition ».

    Pour répondre à votre question, l’utilisateur sera donc amené à répondre plusieurs fois à une même phrase car son objectif sera d’acquérir la règle correspondante.

    Une règle est réputée acquise une fois pour toutes (et ce, même si l’utilisateur se trompe ultérieurement sur les phrases associées à cette règle). La possibilité est néanmoins offerte à l’utilisateur de « réinitialiser » l’acquisition d’une règle, ce qui reviendra à considérer qu’il n’a encore jamais répondu aux phrases rattachées à cette règle (le statut repasse à l’état « à acquérir ».)

    Je ne sais pas si ces règles de gestion que j'espère claires bouleversent ou non le MCD actuel. Je m’interroge notamment sur le fait de savoir si l’attribut SeuilAcquisition suffit à répondre à la problématique de l’acquisition d’une règle décrite supra.

    Je suis preneur de vos lumières renouvelées sur le sujet. Merci.

  13. #13
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    Citation Envoyé par almoha
    Désolé pour les redites.
    Ne soyez pas désolé, je suis souvent distrait, donc de mon côté, bis repetita placent



    Citation Envoyé par almoha
    L’utilisateur choisit une règle d’orthographe à aborder (son choix se fait au travers de l’arborescence partie/sous-partie/rubrique).
    Le MCD permet de prendre en compte cette arborescence, donc il ne devrait pas y avoir de problème de ce côté-là.



    Citation Envoyé par almoha
    L’application affiche successivement toutes les phrases rattachées à cette règle.
    Les règles et les phrases ont aussi été prises en compte dans le MCD, donc ça devrait aller là aussi.



    Citation Envoyé par almoha
    Pour chaque phrase, l’utilisateur doit déterminer si elle comporte ou non une erreur (la position du mot cliqué permet de vérifier sa réponse [position 0 si la phrase ne comporte aucun mot erroné])
    Au vu de la partie correspondante du MCD (voir ci-dessous), on peut mémoriser la réponse de l’utilisateur pour chaque phrase à laquelle il a répondu. A charge de l’application de valoriser l’attribut Position (table REPONDRE au stade SQL), en fonction de la réponse de l’utilisateur. Si celui-ci a cliqué sur le bouton « Pas d’erreur », Position prendra la valeur 0. Sa réponse sera considérée comme correcte si l’attribut Position de la table PHRASE vaut également 0 pour cette phrase. Plus généralement, si l’utilisateur a fourni une réponse, celle-ci est considérée comme correcte si l’attribut Position de la table REPONDRE et l’attribut Position de la table PHRASE ont la même valeur pour la phase en question.

    Tant que l’utilisateur n’a pas fourni de réponse pour une phrase donnée, on considère qu’il a faux pour cette phrase.

    Sommes-nous en phase ?







    Citation Envoyé par almoha
    Après chaque validation de phrase, l’application indiquera à l’utilisateur si la réponse fournie est correcte ou non ; affichera la phrase correctement orthographiée ; affichera la règle d’orthographe à laquelle se rattache la phrase.
    Comme j’en ai déjà fait mention, si l’attribut Position de la table PHRASE est égal à 0, alors l’attribut Texte de cette table contient déjà la bonne réponse, donc inutile de prévoir un doublon dans la table CORRIGE qui ne sert qu’en cas de phrase proposée contenant une erreur, avec une mauvaise réponse de la part de l’utilisateur. Si la phrase proposée à l’utilisateur ne contient pas d’erreur et que celui-ci se plante, si on lui affiche quelque chose, je suppose qu’il s’agira de la phrase contenue dans l’attribut Texte de la tale PHRASE. Votre avis ?


    MCD





    MLD






    Citation Envoyé par almoha
    Une fois toutes les phrases de la règle en question passées en revue, l’application affichera le nombre de bonnes et mauvaises réponses.
    Ce qu’on saura faire par comparaison des attributs Position des tables PHRASE et REPONDRE.


    Citation Envoyé par almoha
    Par défaut une règle a le statut « à acquérir » => ce statut concerne les règles que l’utilisateur n’a pas encore étudiées en répondant aux questions associées.
    Grâce à la table REPONDRE, on sait où en est un utilisateur donné par rapport aux phrases. Comme une phrase fait référence à une règle, on sait donc où en est l’utilisateur par rapport à une règle donnée, plus généralement par rapport à un ensemble de règles.

    Par contre, le MCD ne permet pas de savoir quelles sont les règles choisies par l’utilisateur, avant qu’il n’ait commencé à fournir ses réponses. Il faut donc faire évoluer le MCD, en ajoutant l’ association nécessaire, connectant les entités-types REGLE et UTILISATEUR, appelons-la par exemple CHOISIR :





    Mais selon cette modélisation, rien n’empêche qu’un utilisateur choisisse les règles R1, R2, R3, et réponde à des phrases appartenant à des règles différentes, disons R4, R5 et R6... Dans ce genre de situation, il est d’usage de modéliser ce qu’on appelle une contrainte d’inclusion, à partir de l’énoncé : « Chaque phrase à laquelle un utilisateur a répondu doit être une phrase appartenant à la règle qu’il a choisie ». On pourrait en rester là, et prendre en compte la contrainte au stade SQL, au moyen d’un trigger. Mais on peut déjà agir au niveau du MCD :

    1) On déguise l’association CHOISIR en entité-type (identifiée relativement à UTILISATEUR et REGLE) ;

    2) On identifie PHRASE relativement à REGLE ;

    3) On supprime la patte d’association connectant REPONDRE et UTILISATEUR, et à la place on crée une patte d’association entre REPONDRE et CHOISIR.

    Le MCD devient :




    L’identification de PHRASE relativement à REGLE fera qu’au stade du MLD, l’attribut RegleId sera propagé jusqu’à la table REPONDRE. De même, l’entité-type CHOISIR étant identifiée relativement à REGLE, l’attribut RegleId sera propagé jusqu’à la table REPONDRE, via CHOISIR. La table REPONDRE sera dotée de deux attributs RegleId : on en éliminera un (manuellement) et le tour sera joué : la contrainte d’inclusion sera garantie de facto.

    Je ne sais pas si l’outil que vous utilisez permet de mettre en œuvre l’identification relative (vous me direz), à défaut vous aurez un peu plus de pain sur la planche que moi pour bricoler le MLD, en tout cas il doit être le suivant pour la partie qui nous intéresse :





    Ainsi, la table PHRASE a pour clé primaire la paire {RegleId, PhraseId}, elle fait référence à la table REGLE au moyen de la clé étrangère {RegleId}.

    La table CHOISIR a pour clé primaire la paire {UtilisateurId, RegleId}, elle fait référence à la table UTILISATEUR au moyen de la clé étrangère {UtilisateurId}, elle fait référence à la table REGLE au moyen de la clé étrangère {RegleId}.

    La table REPONDRE a pour clé primaire le triplet {UtilisateurId, RegleId, PhraseId}, elle fait référence à la table CHOISIR au moyen de la clé étrangère {UtilisateurId, RegleId}, elle fait référence à la table PHRASE au moyen de la clé étrangère {RegleId, PhraseId}.



    Citation Envoyé par almoha
    a) Par défaut une règle a le statut « à acquérir » => ce statut concerne les règles que l’utilisateur n’a pas encore étudiées en répondant aux questions associées.
    Alternative :

    1) Définir un attribut Statut hébergé dans l’entité-type CHOISIR, mais redondant avec ce qu’on sait déjà via REPONDRE : il n’en est qu’une conséquence logique. Puisque ce nouvel attribut correspond à un résultat de calcul, il faudra mettre en œuvre le trigger qui va bien pour le mettre à jour à chaque mise à jour (création, modification, surpression de ligne) de la table REPONDRE (éviter de le faire au niveau de l’application).

    2) Ne pas définir cet attribut Statut : au moment où l’on a besoin de l’information, une requête réalise le calcul correspondant. La requête sera probablement complexe mais on pourra l’encapsuler dans une vue.



    Citation Envoyé par almoha
    b) Le statut passe à l’état « acquis » si l’utilisateur a répondu au moins trois fois correctement à toutes les phrases rattachées à ladite règle (10, 15 , 20 ou 40 phrases selon les règles).
    c) Dès que l’utilisateur commence à étudier une règle dans l’optique de l’acquérir, le statut de la règle passe à l’état intermédiaire « en cours d’acquisition ».
    A priori, ceci milite pour la création de l’attribut Statut dans la table CHOISIR et la mise en œuvre d’un trigger comme je viens de l’évoquer.



    Citation Envoyé par almoha
    Pour répondre à votre question, l’utilisateur sera donc amené à répondre plusieurs fois à une même phrase car son objectif sera d’acquérir la règle correspondante.
    La clé primaire de la table REPONDRE dans sa dernière version est la suivante :

    {UtilisateurId, RegleId, PhraseId}

    Prenons le cas où Raoul (UtilisateurId = 123) a déjà répondu à la phrase « Le petit chat est morts » (PhraseId = 3) appartenant à la règle « Le pluriel des noms : cas généraux » (RegleId = 1).

    La table REPONDRE contient donc la valeur de clé suivante : <123, 1, 3> et du fait de la contrainte d’unicité caractérisant les clés, on ne pourra pas avoir plus d’une fois cette valeur. On est donc amené à compter les fois où Raoul a répondu, en définissant un attribut supplémentaire, appelons-le Compteur, venant compléter la clé :

    {UtilisateurId, RegleId, PhraseId, Compteur}

    Ainsi, on pourra compter le nombre de fois où Raoul aura répondu à la même phrase : <123, 1, 3, 1>, <123, 1, 3, 2>, etc.


    Conséquence sur le MCD : Merise nous impose de définir une entité-type factice, appelons-la COMPTEUR (ou tout autre nom qui vous conviendrait), branchée sur l’association REPONDRE :





    COMPTEUR est une entité-type factice et n’a donc pas à faire l’objet d’une table dans le MLD, puisque par dérivation on aura atteint notre but, à savoir doter la clé primaire de la table REPONDRE de l’attribut qui va bien. Avec PowerAMC on a la possibilité de demander à ce que cette table ne soit pas générée. Si l’outil que vous utilisez force la génération, vous supprimerez la table manuellement.

    MLD attendu pour cette partie :




    (La flèche bleue n’est que gribouillage de ma part, histoire d’attirer l’attention sur le nouvel attribut).



    Citation Envoyé par almoha
    Une règle est réputée acquise une fois pour toutes (et ce, même si l’utilisateur se trompe ultérieurement sur les phrases associées à cette règle). La possibilité est néanmoins offerte à l’utilisateur de « réinitialiser » l’acquisition d’une règle, ce qui reviendra à considérer qu’il n’a encore jamais répondu aux phrases rattachées à cette règle (le statut repasse à l’état « à acquérir ».)
    Cela ne devrait pas avoir de conséquence sur le MCD.



    Citation Envoyé par almoha
    Je ne sais pas si ces règles de gestion que j'espère claires bouleversent ou non le MCD actuel. Je m’interroge notamment sur le fait de savoir si l’attribut SeuilAcquisition suffit à répondre à la problématique de l’acquisition d’une règle décrite supra.
    Aménagement, oui, bouleversement, non (du moins pour le moment !) Quant à l’attribut SeuilAcquisition, je pense qu’il y a comme un quiproquo, j’en ai mal perçu la finalité. Pourriez-vous m’en dire plus à son sujet ?


    Citation Envoyé par almoha
    Je suis preneur de vos lumières renouvelées sur le sujet.
    Heu... Au royaume des aveugles... Si les explications que je viens de fournir vous paraissent fumeuses, n’hésitez pas à faire part de vos commentaires...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  14. #14
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Bonjour fsmrel,

    Encore un grand merci pour vos commentaires très étayés et pertinents sur mon projet.
    Pour répondre à votre question, j'utilise l'outil gratuit Jmerise.

    Au vu de la partie correspondante du MCD (voir ci-dessous), on peut mémoriser la réponse de l’utilisateur pour chaque phrase à laquelle il a répondu. A charge de l’application de valoriser l’attribut Position (table REPONDRE au stade SQL), en fonction de la réponse de l’utilisateur. Si celui-ci a cliqué sur le bouton « Pas d’erreur », Position prendra la valeur 0. Sa réponse sera considérée comme correcte si l’attribut Position de la table PHRASE vaut également 0 pour cette phrase. Plus généralement, si l’utilisateur a fourni une réponse, celle-ci est considérée comme correcte si l’attribut Position de la table REPONDRE et l’attribut Position de la table PHRASE ont la même valeur pour la phase en question.

    Tant que l’utilisateur n’a pas fourni de réponse pour une phrase donnée, on considère qu’il a faux pour cette phrase.

    Sommes-nous en phase ?
    Oui, je suis d'accord.

    Comme j’en ai déjà fait mention, si l’attribut Position de la table PHRASE est égal à 0, alors l’attribut Texte de cette table contient déjà la bonne réponse, donc inutile de prévoir un doublon dans la table CORRIGE qui ne sert qu’en cas de phrase proposée contenant une erreur, avec une mauvaise réponse de la part de l’utilisateur.Si la phrase proposée à l’utilisateur ne contient pas d’erreur et que celui-ci se plante, si on lui affiche quelque chose, je suppose qu’il s’agira de la phrase contenue dans l’attribut Texte de la tale PHRASE. Votre avis ?
    Je suis d'accord sauf que la table CORRIGE sert aussi si l'utilisateur a fourni la bonne réponse en repérant à raison l'erreur dans une phrase.

    En résumé, après que l'utilisateur a validé son choix :

    - la phrase contenue dans l'attribut CorrigeTexte de la table CORRIGE s'affiche si la phrase qui était proposée était erronée, que l'utilisateur ait fourni ou non la bonne réponse
    - la phrase contenue dans l'attribut Texte de la table PHRASE s'affiche si la phrase qui était proposée était correcte, que l'utilisateur ait fourni la bonne réponse (en cliquant sur "pas d'erreur") ou pas.

    Quant à l’attribut SeuilAcquisition, je pense qu’il y a comme un quiproquo, j’en ai mal perçu la finalité. Pourriez-vous m’en dire plus à son sujet ?
    Lorsque l’utilisateur choisit une règle d’orthographe à aborder, il devra être mesure de savoir si cette règle n’a jamais été étudiée (statut « à acquérir »), l’a été en partie (statut « en cours d’acquisition ») ou acquise totalement (pour avoir déjà répondu 3 fois correctement à l’ensemble des phrases rattachées à la règle : statut « acquis »).

    Comme vous l’indiquez, cette organisation milite pour la création d’un attribut « Statut » que vous positionnez dans l’entité-type CHOISIR.
    A ce sujet, pourquoi doit-on la faire figurer dans cette entité au lieu de l’entité-type REGLE ?

    S’agissant de l’attribut SeuilAcquisition de l’entité-type REGLE, il prend pour valeur le nombre de phrases rattachées à une règle. Dès lors quel est le rôle de cet attribut dans le fait de savoir si une règle est acquise ou non ? Et comment est gérée son interdépendance avec l’attribut « statut » ?

    L’attribut SeuilAcquisition est-il toujours nécessaire en présence de l’attribut Statut, dès lors que ce dernier est mis à jour par le biais du trigger dont vous parlez (déclenchement à la mise à jour de la table REPONDRE) ?

    À titre d’exemple, pour le statut des règles :

    - La règle A comporte 20 phrases -> l’utilisateur n’a jamais étudié cette règle -> statut par défaut « à acquérir ».
    - La règle B comporte 15 phrases -> l’utilisateur a commencé à étudier cette règle mais ne l’a pas encore acquise -> le trigger passe le statut à « en cours d’acquisition ».
    - La règle C comporte 40 phrases -> l’utilisateur a répondu 3 fois correctement à l’ensemble des phrases rattachées à cette règle -> le trigger passe le statut à « acquis ».
    - Plus tard, l’utilisateur souhaite réinitialiser l’acquisition de la règle C (car il constate qu’il commet désormais des erreurs dans l’application de cette règle) -> le trigger repasse le statut à « acquérir ».

    Pour ne m’y être jamais frotté, j’avoue appréhender l’écriture de ces triggers…

    Heu... Au royaume des aveugles... Si les explications que je viens de fournir vous paraissent fumeuses, n’hésitez pas à faire part de vos commentaires...
    Je ne voulais surtout pas suggérer que vos explications étaient absconses. C’est tout le contraire ! Vos commentaires sont on ne peut plus instructifs

  15. #15
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,



    Citation Envoyé par almoha
    Pour répondre à votre question, j'utilise l'outil gratuit Jmerise.
    En fait, je voulais savoir si l’outil, en l’occurrence Jmerise, permet de mettre en oeuvre l’identification relative. Qu’en est-il ?



    Citation Envoyé par almoha
    Je suis d'accord sauf que la table CORRIGE sert aussi si l'utilisateur a fourni la bonne réponse en repérant à raison l'erreur dans une phrase.
    Bien entendu. Du moment qu’une phrase comporte intentionnellement une erreur, il est évident que la phrase correcte doit être présente dans la table CORRIGE.

    J’ai sans doute été un peu ambigu dans ma prose, je simplifie donc ainsi :

    « Inutile de prévoir un doublon dans la table CORRIGE qui ne sert qu’en cas de phrase proposée contenant intentionnellement une erreur. »



    Citation Envoyé par almoha
    S’agissant de l’attribut SeuilAcquisition de l’entité-type REGLE, il prend pour valeur le nombre de phrases rattachées à une règle. Dès lors quel est le rôle de cet attribut dans le fait de savoir si une règle est acquise ou non ? Et comment est gérée son interdépendance avec l’attribut « statut » ?
    Puisque l’attribut SeuilAcquisition sert en fait à savoir combien de phrases sont rattachées à une règle, il ne dépend d’aucun autre attribut, si ce n’est l’identifiant de la table REGLE. Il pourrait même ne pas exister, puisqu’il est calculable au moyen de la requête suivante :

    
    SELECT  RegleId, COUNT(*) 
    FROM    PHRASE 
    GROUP BY RegleId
    ;
    
    
    Pour éviter toute confusion, de mon côté je renomme très prosaïquement SeuilAcquisition en NbPhrases, mais si vous préférez un autre nom, n’hésitez pas.

    On pourrait mettre en œuvre une vue et consulter celle-ci, plutôt que la table REGLE (dépourvue de cet attribut) :

    
    CREATE TABLE REGLE 
    (
            RegleId              INT             NOT NULL
          , ElementId            INT             NOT NULL        
          , RegleTexte           VARCHAR(64)     NOT NULL
        , CONSTRAINT REGLE_PK PRIMARY KEY (RegleId)
        , CONSTRAINT REGLE_ELEMENT_FK FOREIGN KEY (ElementId)
          REFERENCES ELEMENT (ElementId)
    ) ;
    
    CREATE TABLE PHRASE 
    (
            RegleId              INT             NOT NULL
          , PhraseId             INT             NOT NULL
          , DifficulteId         INT             NOT NULL
          , Position             INT             NOT NULL
          , Texte                VARCHAR(64)     NOT NULL
        , CONSTRAINT PHRASE_PK PRIMARY KEY (RegleId, PhraseId)
        , CONSTRAINT PHRASE_REGLE_FK FOREIGN KEY (RegleId)
          REFERENCES REGLE (RegleId)
        , CONSTRAINT PHRASE_DIFFICULTE_FK FOREIGN KEY (DifficulteId)
          REFERENCES DIFFICULTE (DifficulteId)
    ) ;
    
    INSERT INTO REGLE (RegleId, ElementId, RegleTexte) VALUES
        (1, 4, 'Le pluriel des noms : cas généraux')
      , (2, 4, 'est-ce que') 
      , (3, 4, 'a ; à')
      , (4, 4, 'confusions')   
    ;
    
    INSERT INTO PHRASE (RegleId, PhraseId, DifficulteId, Position, Texte) VALUES
        (1, 1, 1, 5, 'Le petit chat est morts')
      , (1, 2, 2, 5, 'Il a un petit soucis')
      , (3, 1, 2, 0, 'Je vais à Paris')
      , (3, 2, 2, 0, 'Pierre a faim')
      , (3, 3, 4, 0, 'Ce crayon est a moi')  
      , (4, 1, 1, 2, 'Il et fort et agile')
      , (4, 2, 1, 0, 'Elle est grande')
      , (4, 3, 4, 0, 'Il aime le cuissot de chevreuil')
      , (4, 4, 4, 5, 'Il aime aussi le cuissot de veau')
      , (4, 5, 3, 0, 'C''est une imbécillité')
    ;
    
    CREATE VIEW REGLE_V (RegleId, ElementId, RegleTexte, NbPhrases) AS
    SELECT x.RegleId, ElementId, RegleTexte, y.NbPhrases
    FROM   REGLE AS x JOIN
           (SELECT RegleId, COUNT(*) AS NbPhrases
            FROM   PHRASE
            GROUP BY RegleId
           ) AS y
          ON x.RegleId = y.RegleId
    UNION ALL
    SELECT RegleId, ElementId, RegleTexte, 0
    FROM   REGLE as x
    WHERE NOT EXISTS 
           (SELECT ''
            FROM   PHRASE AS y
            WHERE  x.RegleId = y.RegleId
           ) 
    ;
     
    
    Si on exécute la requête suivante :

     
    
    SELECT * FROM REGLE_V 
    ORDER BY RegleId ;
    
    
    Au résultat, on doit obtenir ceci :

    
    RegleId    ElementId    RegleTexte                            NbPhrases
          1            4    Le pluriel des noms : cas généraux            2
          2            4    est-ce que                                    0
          3            4    a ; à                                         3
          4            4    confusions                                    5
    
    
    Le problème est que si la création de la vue REGLE_V ne pose aucun problème avec les autres SGBD, elle est manifestement trop compliquée pour MySQL qui baisse les bras et nous gratifie du message suivant :

    « Error Code: 1349. View's SELECT contains a subquery in the FROM clause »

    Les carences de MySQL incitent donc à mettre en œuvre l’attribut NbPhrases :

    
    CREATE TABLE REGLE 
    (
            RegleId              INT             NOT NULL
          , ElementId            INT             NOT NULL        
          , RegleTexte           VARCHAR(64)     NOT NULL
          , NbPhrases            INT             NOT NULL
        , CONSTRAINT REGLE_PK PRIMARY KEY (RegleId)
        , CONSTRAINT REGLE_ELEMENT_FK FOREIGN KEY (ElementId)
          REFERENCES ELEMENT (ElementId)
     ) ;
    
    

    Maintenant, il paraît difficile de contrôler automatiquement (par trigger) que le nombre réel de lignes par règle dans la table PHRASE est bien égal à la valeur de l’attribut NbPhrases. Tout au plus il sera à la charge de l’application de le vérifier au moment opportun (comme disait Bach à propos de la musique : « La bonne note au bon moment »), au moyen d’une requête du genre :

    
    -- Afficher les règles pour lesquelles le nombre de phrases (table PHRASE) est différent de la valeur de NbPhrases (table REGLE)
    
    SELECT x.RegleId, x.RegleTexte, x.NbPhrases AS NbPhrasesPrevu, y.NbPhrases AS NbPhrasesReel
    FROM   REGLE AS x JOIN 
           (SELECT RegleId, COUNT(*) AS NbPhrases 
            FROM PHRASE
            GROUP BY RegleId) AS y
          ON x.RegleId = y.RegleId
          AND x.NbPhrases <> y.NbPhrases 
    ;  
    
    
    En passant, la vue PHRASE_SEUIL_ACQUISITION (cf. message #11) est à côté de la plaque et disparaît.


    En ce qui concerne l’attribut Statut, vous avez décrit son cycle de vie. Supposons que cet attribut existe effectivement. Puisqu’il concerne la situation d’un utilisateur par rapport à une règle, il appartient à (l’en-tête de) la table CHOISIR. Pour y voir clair, prenons l’exemple de l’utilisateur Raoul qui a choisi la règle « Le pluriel des noms : cas généraux ».

    Table des utilisateurs :

    
    CREATE TABLE UTILISATEUR
    (
            UtilisateurId        INT             NOT NULL
          , UtilisateurNom       VARCHAR(32)     NOT NULL         
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (UtilisateurId)        
    ) ;
    
    INSERT INTO UTILISATEUR (UtilisateurId, UtilisateurNom) VALUES
        (1, 'Fernand'), (2, 'Raoul'), (3, 'Paul') 
     ;   
    
    
    Table CHOISIR :

    
    CREATE TABLE CHOISIR
    (
            UtilisateurId        INT             NOT NULL
          , RegleId              INT             NOT NULL
          , Statut               VARCHAR(64)     NOT NULL DEFAULT 'à acquérir'
         , CONSTRAINT CHOISIR_PK PRIMARY KEY (UtilisateurId, RegleId)  
        , CONSTRAINT CHOISIR_UTILISATEUR_FK FOREIGN KEY (UtilisateurId) 
          REFERENCES UTILISATEUR (UtilisateurId) ON DELETE CASCADE    
    ) ;
    
    
    Dans quelles conditions valorise-t-on l’attribut Statut à « à acquérir » ?

    1) Quand on crée une 1re ligne dans la table CHOISIR pour Raoul (je n’ai pas fait figurer RegleId dans l’INSERT, car j’ai fait figurer « à acquérir » comme valeur par défaut dans l’instruction CREATE TABLE) :

    
    INSERT INTO CHOISIR (UtilisateurId, RegleId) VALUES
        (2, 1)    
    ;
    
    
    2) Quand Raoul souhaite réinitialiser l’acquisition de la règle. On utilise alors une instruction UPDATE :

    
    UPDATE CHOISIR SET Statut = 'à acquérir' WHERE UtilisateurId = 2 ;
    
    
    Mais attention ! Il faut penser à faire le ménage dans la table REPONDRE, sinon Raoul sera censé avoir déjà fourni des réponses...

    Pour pallier nos éventuelles étourderies peut-on envisager de mettre en place un trigger qui fasse ce ménage ? Si le statut avant réinitialisation est autre que 'à acquérir', ça doit être possible, mais s’il est déjà 'à acquérir', on ne sait pas a priori si Raoul a demandé une réinitialisation, on risque peut-être un ménage intempestif : votre avis ?

    Pour le moment j’en reste là, je reviendrai dès que je peux.

    En attendant, bon courage...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  16. #16
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Bonjour fsmrel,

    Les carences de MySQL incitent donc à mettre en œuvre l’attribut NbPhrases
    Je suis votre conseil et retiens donc la mise en œuvre de cet attribut dans la table REGLE.

    Concernant le valorisation de l'attribut "Statut" de la table CHOISIR, en résumé :

    1) le statut passe à "en cours d'acquisition" quand on crée une 1re ligne dans la table CHOISIR.

    2) le statut passe à "acquis" dès lors que, dans la table REPONDRE, on peut identifier que toutes les phrases d'une règle donnée ont été par trois fois au moins correctement répondues par un utilisateur.

    3) le statut repasse à "à aquérir" si l'utilisateur choisit de réinitialiser l'acquisition d'une règle :

    Il faut penser à faire le ménage dans la table REPONDRE [...] Si le statut avant réinitialisation est autre que 'à acquérir', ça doit être possible
    L'utilisateur ne peut réinitialiser qu'une règle ayant le statut acquis.

    Je n'ai jamais utilisé les triggers. Mais si j'ai bien compris, schématiquement :

    - le trigger 1 (statut "en cours d'acquisition") doit regarder dans la table CHOISIR si l'utilisateur a choisi une règle. Si c'est le cas, la règle considérée sera "en cours d'acquisition" et le restera tant qu'elle ne sera pas acquise.

    - le trigger 2 (statut "acquis") doit regarder dans la table REPONDRE si l'utilisateur a répondu au moins trois fois correctement à toutes les phrases rattachées à une règle. Si c'est le cas, la règle sera "acquise" et le restera tant qu'elle ne sera pas "réinitialisée" (=> statut "à acquérir").
    Concernant ce trigger, j'imagine qu'il doit aussi tenir compte de l'attribut NbPhrases de la table REGLE.

    - l'utilisateur ayant choisi une règle à réinitialiser (=> requête UPDATE SET Statut "à acquérir"), le trigger 3 (statut "à acquérir") fait le ménage dans la table REPONDRE pour supprimer toutes les réponses de l'utilisateur concernant la règle réinitialisée.

    Que pensez-vous de ce déroulé théorique ?

    En fait, je voulais savoir si l’outil, en l’occurrence Jmerise, permet de mettre en oeuvre l’identification relative. Qu’en est-il ?
    Jmerise prévoit l'implémentation de l'indentification relative. Mais lors du passage au MLD, il semble ne pas s'y retrouver, tout comme pour la réflexivité.

    Merci encore de votre intérêt pour mon projet

  17. #17
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    Citation Envoyé par almoha
    Concernant le valorisation de l'attribut "Statut" de la table CHOISIR, en résumé :

    1) le statut passe à "en cours d'acquisition" quand on crée une 1re ligne dans la table CHOISIR.

    2) le statut passe à "acquis" dès lors que, dans la table REPONDRE, on peut identifier que toutes les phrases d'une règle donnée ont été par trois fois au moins correctement répondues par un utilisateur.

    3) le statut repasse à "à acquérir" si l'utilisateur choisit de réinitialiser l'acquisition d'une règle.
    Nous sommes en phase pour les deux premiers points. Pour ce qui concerne le la réinitialisation, je mets en suspens. En effet, je suis en train d’essayer de mettre au point le trigger automatisant l’évolution du statut, mais il n’est pas encore totalement opérationnel (euphémisme...), c’est assez compliqué, mais je ne désespère pas...


    Citation Envoyé par almoha
    Que pensez-vous de ce déroulé théorique ?
    Au plan théorique, pas de problème, mais, comme je viens d’en parler, la programmation du trigger n’est pas simple...


    J’ai fait un évoluer le MCD.

    Comme je l’ai déjà écrit, j’ai renommé l’attribut « SeuilAcquisition » en « NbPrases » (entité-type REGLE), mais si ce dernier nom ne vous convient pas, on peut revenir en arrière, ou encore retenir un nom qui vous conviendrait mieux.

    L’entité-type CHOISIR est dotée d’un attribut « Compteur » (calculé par le trigger) permettant de connaître le nombre de tours de manège, le nombre de fois où Raoul a répondu à toutes les questions. Quand Compteur passe à 3, le statut passe à « acquis ». Il peut être intéressant de savoir où en est Raoul : 0, 1, 2, 3 (voire plus) tours de manège complets : vous me direz.

    L’association REPONDRE s’est métamorphosée en entité-type. En effet, s on conserve les séries de réponses de Raoul, il faut alors les dédoublonner, d’où l’apparition d’un attribut « Fois » participant à l’identification de REPONDRE.

    MCD (hors nomenclature) :





    MLD





    Dès que, je replongerai dans la programmation du trigger...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  18. #18
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,


    A propos du trigger, fausse alerte, j’avais testé avec un jeu d’essai mal ficelé.

    Voici ma dernière proposition. Je rappelle que l’objet est d’automatiser la détermination du statut, jusqu’au passage à « acquis ».

    Si le trigger vous pose un problème de compréhension, posez vos questions (avant qu’il ne me faille un bon moment pour le réinterpréter à mon tour...)

    Éléments du script SQL :

    1) Remise à zéro du système

    
    DROP TABLE IF EXISTS REPONDRE ;
    DROP TABLE IF EXISTS CHOISIR ;
    DROP TABLE IF EXISTS UTILISATEUR ;
    DROP TABLE IF EXISTS CORRIGE ;
    DROP TABLE IF EXISTS PHRASE ;
    DROP TABLE IF EXISTS DIFFICULTE ;
    DROP TABLE IF EXISTS COMPOSITION ;
    DROP TABLE IF EXISTS REGLE ;
    DROP TABLE IF EXISTS ELEMENT ;
    DROP TABLE IF EXISTS TYPE_ELEMENT ;
    
    
    2) Définition des tables

    
    CREATE TABLE TYPE_ELEMENT 
    (
            TypeElementId        INT             NOT NULL
          , TypeElementLibelle   VARCHAR(16)     NOT NULL
        , CONSTRAINT TYPE_ELEMENT_PK PRIMARY KEY (TypeElementId)
    ) ;
    
    CREATE TABLE ELEMENT 
    (
            ElementId            INT             NOT NULL
          , TypeElementId        INT             NOT NULL
          , ElementTexte         VARCHAR(64)     NOT NULL
        , CONSTRAINT ELEMENT_PK PRIMARY KEY (ElementId)
        , CONSTRAINT ELEMENT_TYPE_ELEMENT_FK FOREIGN KEY (TypeElementId)
          REFERENCES TYPE_ELEMENT (TypeElementId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE COMPOSITION 
    (
            ElementComposantId       INT             NOT NULL
          , ElementComposeId         INT             NOT NULL
        , CONSTRAINT COMPOSITION_ELEMENT_COMPOSANT_FK FOREIGN KEY (ElementComposantId)
          REFERENCES ELEMENT (ElementId) ON DELETE CASCADE
        , CONSTRAINT COMPOSITION_ELEMENT_COMPOSE_FK FOREIGN KEY (ElementComposeId)
          REFERENCES ELEMENT (ElementId)      
    ) ;
    
    CREATE TABLE REGLE 
    (
            RegleId              INT             NOT NULL
          , ElementId            INT             NOT NULL        
          , RegleTexte           VARCHAR(64)     NOT NULL
          , NbPhrases            INT             NOT NULL
        , CONSTRAINT REGLE_PK PRIMARY KEY (RegleId)
        , CONSTRAINT REGLE_ELEMENT_FK FOREIGN KEY (ElementId)
          REFERENCES ELEMENT (ElementId)
     ) ;
    
    CREATE TABLE DIFFICULTE 
    (
            DifficulteId         INT             NOT NULL
          , DifficulteTexte      VARCHAR(32)     NOT NULL
        , CONSTRAINT DIFFICULTE_PK PRIMARY KEY (DifficulteId)
    ) ;
    
    CREATE TABLE PHRASE 
    (
            RegleId              INT             NOT NULL
          , PhraseId             INT             NOT NULL
          , DifficulteId         INT             NOT NULL
          , Position             INT             NOT NULL
          , Texte                VARCHAR(64)     NOT NULL
        , CONSTRAINT PHRASE_PK PRIMARY KEY (RegleId, PhraseId)
        , CONSTRAINT PHRASE_REGLE_FK FOREIGN KEY (RegleId)
          REFERENCES REGLE (RegleId)
        , CONSTRAINT PHRASE_DIFFICULTE_FK FOREIGN KEY (DifficulteId)
          REFERENCES DIFFICULTE (DifficulteId)
    ) ;
    
    CREATE TABLE CORRIGE 
    (
            RegleId              INT             NOT NULL
          , PhraseId             INT             NOT NULL
          , CorrigeTexte         VARCHAR(64)     NOT NULL
        , CONSTRAINT CORRIGE_PK PRIMARY KEY (RegleId, PhraseId)
        , CONSTRAINT CORRIGE_PHRASE_FK FOREIGN KEY (RegleId, PhraseId)
          REFERENCES PHRASE (RegleId, PhraseId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE UTILISATEUR
    (
            UtilisateurId        INT             NOT NULL
          , UtilisateurNom       VARCHAR(32)     NOT NULL         
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (UtilisateurId)        
    ) ;
    
    CREATE TABLE CHOISIR
    (
            UtilisateurId        INT             NOT NULL
          , RegleId              INT             NOT NULL
          , Statut               VARCHAR(24)     NOT NULL DEFAULT 'à acquérir'
          , Compteur             INT             NOT NULL DEFAULT 0 – nombre de fois où Raoul a bien répondu à toutes les phrases de la règle
        , CONSTRAINT CHOISIR_PK PRIMARY KEY (UtilisateurId, RegleId)  
        , CONSTRAINT CHOISIR_UTILISATEUR_FK FOREIGN KEY (UtilisateurId) 
          REFERENCES UTILISATEUR (UtilisateurId) ON DELETE CASCADE    
    ) ;
    
    CREATE TABLE REPONDRE
    (
            UtilisateurId        INT             NOT NULL
          , RegleId              INT             NOT NULL
          , PhraseId             INT             NOT NULL
          , Fois                 INT             NOT NULL
          , Position             INT             NOT NULL
        , CONSTRAINT REPONDRE_PK PRIMARY KEY (UtilisateurId, RegleId, PhraseId, Fois)  
        , CONSTRAINT REPONDRE_CHOISIR_FK FOREIGN KEY (UtilisateurId, RegleId) 
          REFERENCES CHOISIR (UtilisateurId, RegleId) ON DELETE CASCADE    
        , CONSTRAINT REPONDRE_PHRASE_FK FOREIGN KEY (RegleId, PhraseId) 
          REFERENCES PHRASE (RegleId, PhraseId)
    ) ;
    
    

    3) Le trigger calculant le statut :

    
    COMMIT ;
    
    DELIMITER GO
    
    CREATE TRIGGER REPONDRE_INSERT_AFTER AFTER INSERT ON REPONDRE 
    FOR EACH ROW
        BEGIN
            SET @StatutAcquerir = 'à acquérir' ;
            SET @StatutEnCours = 'acquisition en cours' ;
            SET @StatutAcquis = 'acquis' ;
     
     -- Raoul a répondu au moins une fois à une phrase d'une règle donnée. Si son statut pour cette règle est 'à acquérir', 
     -- ce statut passe à 'acquisition en cours', que sa réponse soit bonne ou mauvaise.
     
            SET @StatutRaoul = (SELECT Statut 
                                FROM   CHOISIR 
                                WHERE  UtilisateurId = new.UtilisateurId 
                                  AND  RegleId = new.RegleId) ;
                                
            IF @StatutRaoul = @StatutAcquerir THEN                            
                UPDATE CHOISIR SET Statut =  @StatutEnCours 
                    WHERE UtilisateurId = new.UtilisateurId 
                      AND RegleId = new.RegleId ;
            END IF ;
     
    -- On récupère le nombre de tours de manège complets déjà réussis par Raoul
    
            SET @CompteurChoisir = (SELECT Compteur
                                    FROM  CHOISIR
                                    WHERE UtilisateurId = new.UtilisateurId 
                                      AND RegleId = new.RegleId) ;
     
    -- On récupère le nombre de phrases auxquelles Raoul n'a pas encore répondu pour la règle en cours
    
            SET @NbPhrasesSansReponse = (SELECT COUNT(*) 
                                         FROM   PHRASE AS x
                                         WHERE  RegleId = new.RegleId
                                           AND  NOT EXISTS
                                               (SELECT ''
                                                FROM   REPONDRE AS y 
                                                WHERE  x.RegleId = y.RegleId
                                                  AND  x.PhraseId = y.PhraseId)
                                        ) ;
    
    -- Si Raoul a répondu à toutes les phrases de la règle en cours, pour chacune d'elles on regarde combien de fois il a bien répondu.
    -- On récupère le plus petit nombre de fois où il a bien répondu à une phrase. 
            
            SET @MinKount = 0 ;
            
            IF @NbPhrasesSansReponse = 0 THEN
                SET @MinKount = (SELECT DISTINCT MIN(Kount) AS MinKount
                                 FROM  (SELECT COUNT(*) AS Kount
                                        FROM   REPONDRE AS x, PHRASE AS y 
                                        WHERE  x.UtilisateurId = new.UtilisateurId AND x.RegleId = new.RegleId                  
                                          AND  x.Regleid = y.Regleid AND x.PhraseId = y.PhraseId AND x.Position = y.Position 
                                        GROUP BY x.UtilisateurId, x.RegleId, x.PhraseId) AS t) ; 
            END IF ;
    
    -- Si le plus petit nombre de fois où Raoul a bien répondu est au moins égal à 3, on fait passer le statut à 'acquis' et on mémorise ce plus petit nombre.
    
            IF @MinKount >= 3 THEN
                UPDATE CHOISIR SET Statut = @StatutAcquis
                                 , Compteur = @MinKount
                    WHERE UtilisateurId = new.UtilisateurId AND RegleId = new.RegleId ; 
     
    -- Si le plus petit nombre de fois où Raoul a bien répondu est inférieur à 3, on mémorise ce plus petit nombre s'il est supérieur à celui déjà mémorisé.
                   
            ELSEIF @MinKount > @CompteurChoisir THEN
                UPDATE CHOISIR SET Compteur = @MinKount
                   WHERE UtilisateurId = new.UtilisateurId AND RegleId = new.RegleId ;
            END IF ;  
        END 
    GO 
    
    DELIMITER ;
    
    

    4) Un petit jeu d’essai

    
    INSERT INTO TYPE_ELEMENT (TypeElementId, TypeElementLibelle) VALUES 
        (1, 'Partie'), (2, 'Sous-partie'), (3, 'Rubrique') ;
        
     -- SELECT * FROM TYPE_ELEMENT ;
    
    INSERT INTO ELEMENT (ElementId, TypeElementId, ElementTexte) VALUES
        (1, 1, 'Formes et accords du verbe')
      , (2, 1, 'Formes et accords du nom, de l''adjectif du verbe')
      , (3, 1, 'Orthographe lexicale, signes graphiques et syntaxe')
      , (4, 1, 'Ces mots que l''on confond')
      , (5, 2, 'Le verbe : ses formes')
      , (6, 2, 'Syntaxe')
      , (7, 3, 'L''infinitif')
      , (8, 3, 'Les noms : leur féminin, leur pluriel')
    ;
     
    -- SELECT * FROM ELEMENT ; 
    
    INSERT INTO COMPOSITION  (ElementComposantId, ElementComposeId) VALUES
        (5,1), (6, 3), (7, 5), (8, 2) 
    ;
    
    -- SELECT * FROM COMPOSITION ; 
     
    INSERT INTO DIFFICULTE (DifficulteId, DifficulteTexte) VALUES
        (1, 'Facile'), (2, 'Assez facile'), (3, 'Piège classique'), (4, 'Niveau Mérimée') ;  
     
     -- SELECT * FROM DIFFICULTE ;
    
    INSERT INTO REGLE (RegleId, ElementId, RegleTexte, NbPhrases) VALUES
        (1, 4, 'Le pluriel des noms : cas généraux', 5)
      , (2, 4, 'est-ce que', 15) 
      , (3, 4, 'a ; à', 2)
      , (4, 4, 'confusions', 6)   
    ;
    
    -- SELECT * FROM REGLE ; 
    
    INSERT INTO PHRASE (RegleId, PhraseId, DifficulteId, Position, Texte) VALUES
        (1, 1, 1, 5, 'Le petit chat est morts')
      , (1, 2, 2, 5, 'Il a un petit soucis')
      , (1, 3, 1, 3, 'Des yeux marrons')
      , (1, 4, 2, 4, 'Il est huit heure')
      , (1, 5, 3, 0, 'Huit cent deux kilos')
      , (3, 1, 2, 0, 'Je vais à Paris')
      , (3, 2, 2, 0, 'Pierre a faim')
      , (3, 3, 4, 0, 'Ce crayon est a moi')  
      , (4, 1, 1, 2, 'Il et fort et agile')
      , (4, 2, 1, 0, 'Elle est grande')
      , (4, 3, 4, 0, 'Il aime le cuissot de chevreuil')
      , (4, 4, 4, 5, 'Il aime aussi le cuissot de veau')
      , (4, 5, 3, 0, 'C''est une imbécillité')
    ;
    
    SELECT * FROM PHRASE ; 
    
    INSERT INTO CORRIGE (RegleId, PhraseId, CorrigeTexte) VALUES
        (4, 1, 'Il est fort et agile')
      , (1, 1, 'Le petit chat est mort')
      , (4, 4, 'Il aime aussi le cuisseau de veau')
      , (1, 2,  'Il a un petit souci')
      , (3, 3, 'Ce crayon est à moi')  
    ;
    
    SELECT * FROM CORRIGE ; 
    
    INSERT INTO UTILISATEUR (UtilisateurId, UtilisateurNom) VALUES
        (1, 'Fernand'), (2, 'Raoul'), (3, 'Paul') 
     ;   
    -- SELECT * FROM UTILISATEUR ;   
    
    -- Raoul choisit la règle 1. Son statut pour cette règle est celui par défaut ('à acquérir').
    -- Le nombre de fois (Compteur) où il a satisfait à l'ensemble des phrase de cette règle est égal à 0 par défaut. 
        
    INSERT INTO CHOISIR (UtilisateurId, RegleId) VALUES
        (2, 1)    
    ;
    
    SELECT *, 'on amorce. Le statut doit être à ''à acquérir'' et Compteur = 0' FROM CHOISIR ; 
    
    INSERT INTO REPONDRE (UtilisateurId, RegleId, PhraseId, Fois, Position) VALUES 
        (2, 1, 1, 1, 5)
      , (2, 1, 1, 2, 5)
      , (2, 1, 1, 3, 5)
      , (2, 1, 1, 4, 5) 
      , (2, 1, 1, 5, 5)
      , (2, 1, 1, 6, 5)
    
      , (2, 1, 2, 1, 5)
      , (2, 1, 2, 2, 5)
      , (2, 1, 2, 3, 0)   -- erreur de Raoul qui n'a donc pas tout acquis 3 fois
      
      , (2, 1, 3, 1, 3)  
      , (2, 1, 3, 2, 3)
      , (2, 1, 3, 3, 3)  
      
      , (2, 1, 4, 1, 4)
      , (2, 1, 4, 2, 4)
      , (2, 1, 4, 3, 4)  
      
      , (2, 1, 5, 1, 0)
      , (2, 1, 5, 2, 0) 
      , (2, 1, 5, 3, 0)  
    ;
    
    SELECT *, 'Le statut doit encore être à ''acquisition en cours'' et Compteur = 2' FROM CHOISIR ;  
    SELECT * FROM REPONDRE ;
    
    SELECT *, '' AS 'CHOISIR'  FROM CHOISIR ;
    
    -- Cette fois-ci Raoul ne se plante pas
    
    INSERT INTO REPONDRE (UtilisateurId, RegleId, PhraseId, Fois, Position) VALUES (2, 1, 2, 4, 5) ;  
    
    SELECT *, '' AS 'CHOISIR'  FROM CHOISIR ;
    
    
    A vous de secouer tout ça. J’espère qu’il ne reste pas trop de défauts dans la cuirasse...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  19. #19
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 365
    Points : 192
    Points
    192
    Par défaut
    Bonjour fsmrel,

    Un grand merci pour le trigger qui, pour l'avoir testé, répond parfaitement à ma problématique.

    L’association REPONDRE s’est métamorphosée en entité-type. En effet, s on conserve les séries de réponses de Raoul, il faut alors les dédoublonner, d’où l’apparition d’un attribut « Fois » participant à l’identification de REPONDRE.
    Dans le jeu d'essai, j'observe que l'attribut "fois" est naturellement valorisé en "dur". Mais comment gérer cette valorisation en production ? Si je comprends bien, il faudrait que l'attribut soit incrémenté à chaque réponse en fonction de l'utilisateur, de la règle et de la phrase... Qu'en pensez-vous ?

    Par ailleurs, pour afficher l'arborescence complète des règles (PARTIE -> le cas échéant SOUS_PARTIE -> le cas échéant RUBRIQUE -> REGLE), je m'interroge sur la requête à effectuer compte tenu de la relation réflexive. Une jointure entre la table COMPOSITION et elle-même est-elle possible ?

  20. #20
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Auto-incrémentation de l'attribut Fois
    Bonsoir almoha,


    Citation Envoyé par almoha
    Un grand merci pour le trigger qui, pour l'avoir testé, répond parfaitement à ma problématique.
    Ouf !

    Avant de traiter de l’arborescence des règles, voyons voir le sort à réserver à l’attribut « Fois » :

    Citation Envoyé par almoha
    Dans le jeu d'essai, j'observe que l'attribut "fois" est naturellement valorisé en "dur". Mais comment gérer cette valorisation en production ? Si je comprends bien, il faudrait que l'attribut soit incrémenté à chaque réponse en fonction de l'utilisateur, de la règle et de la phrase... Qu'en pensez-vous ?
    J’en pense que votre remarque est on ne peut plus légitime

    Pour résoudre ce genre de problème on va utiliser un nouveau trigger qui effectuera l’incrémentation automatique de l’attribut « Fois », donc sans intervention de votre part. On va même cacher cet attribut lors des opérations d’insert (l’encapsuler comme disent les initiés ) ; la partie correspondante du jeu d’essai devient la suivante :

    
    INSERT INTO REPONDRE (UtilisateurId, RegleId, PhraseId, Position) VALUES 
        (2, 1, 1, 5)
      , (2, 1, 1, 5)
      , (2, 1, 1, 5)
      , (2, 1, 1, 5) 
      , (2, 1, 1, 5)
      , (2, 1, 1, 5)  
    
      , (2, 1, 2, 5)
      , (2, 1, 2, 5)
      , (2, 1, 2, 0)   -- erreur => Raoul n'a pas tout acquis 3 fois
      
      , (2, 1, 3, 3)  
      , (2, 1, 3, 3)
      , (2, 1, 3, 3)  
      
      , (2, 1, 4, 4)
      , (2, 1, 4, 4)
      , (2, 1, 4, 4)  
      
      , (2, 1, 5, 0)
      , (2, 1, 5, 0) 
      , (2, 1, 5, 0)  
    ;
    
    SELECT *, 'Le statut doit encore être à ''acquisition en cours'' et Compteur = 2' FROM CHOISIR ;  
    SELECT * FROM REPONDRE ;
    
    SELECT *, '' AS 'CHOISIR'  FROM CHOISIR ;
    
    -- Cette fois-ci Raoul ne se plante pas
    
    INSERT INTO REPONDRE (UtilisateurId, RegleId, PhraseId, Position) VALUES (2, 1, 2, 5) ;  
    
    SELECT *, '' AS 'CHOISIR' FROM CHOISIR ;
    SELECT *, '' AS 'REPONDRE' FROM REPONDRE ;
    
    

    Pour pouvoir évacuer l’attribut « Fois » des instructions INSERT, il faut lui affecter une valeur par défaut quelconque (0 ou 314116 ou ce que vous voulez, peu importe) dans l’instruction CREATE TABLE :

    
    CREATE TABLE REPONDRE
    (
            UtilisateurId        INT             NOT NULL
          , RegleId              INT             NOT NULL
          , PhraseId             INT             NOT NULL
          , Fois                 INT             NOT NULL  DEFAULT 0   
          , Position             INT             NOT NULL
        , CONSTRAINT REPONDRE_PK PRIMARY KEY (UtilisateurId, RegleId, PhraseId, Fois)  
        , CONSTRAINT REPONDRE_CHOISIR_FK FOREIGN KEY (UtilisateurId, RegleId) 
          REFERENCES CHOISIR (UtilisateurId, RegleId) ON DELETE CASCADE    
        , CONSTRAINT REPONDRE_PHRASE_FK FOREIGN KEY (RegleId, PhraseId) 
          REFERENCES PHRASE (RegleId, PhraseId)
    ) ;
    
    

    Le trigger qui réalise l’incrémentation est le suivant :

    
    CREATE TRIGGER REPONDRE_INSERT_BEFORE BEFORE INSERT ON REPONDRE 
    FOR EACH ROW
        BEGIN
            SET new.Fois = (SELECT COALESCE(MAX(Fois) + 1, 1)
                            FROM   REPONDRE
                            WHERE  UtilisateurId = new.UtilisateurId
                              AND  RegleId = new.RegleId
                              AND  PhraseId = new.PhraseId
                           ) ;        
        END
    GO
    
    

    Comment les choses se passent-elles sous le capot ?

    La 1re fois que le trigger prend la main, comme c’est un trigger BEFORE INSERT, la table REPONDRE est vide, donc l’attribut « Fois » ne contient rien (il est marqué NULL). Dans ces conditions, au trigger d’amorcer la pompe, de virer NULL et affecter une valeur à l’attribut. Interprétons cette partie (pour qu’il n’y ait pas d’ambiguïté, je remplace 1 par 7 et 100) :

    SELECT COALESCE(MAX(Fois) + 7, 100)

    En français :

    Agir en fonction de l'état de l’attribut « Fois ». Soit il est marqué NULL (et ne contient donc pas de valeur), auquel cas, on valorise l'attribut à 100 tout en chassant NULL, soit il n’et pas marqué NULL (ce qui est avéré suite au 1er insert réussi), auquel cas prendre sa plus grande valeur actuelle et l’augmenter de 7 unités (c'est-à-dire à partir du 2e insert). C’est à la fonction COALESCE de détecter la [non] nullité de l’attribut.

    Ainsi, après le 1er INSERT :

    
    INSERT INTO REPONDRE (UtilisateurId, RegleId, PhraseId, Position) VALUES 
        (2, 1, 1, 5)
    
    
    Le résultat est le suivant :

    
    UtilisateurId    RegleId    PhraseId    Fois    Position
                2          1           1    100            5
    
    
    Après le 2e insert :

    
    UtilisateurId    RegleId    PhraseId    Fois    Position
                2          1           1    100            5
                2          1           1    107            5
    
    
    Etc.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. [OL-2007] Classer ses mails en catégories, sous catégories
    Par Dae_mon dans le forum VBA Outlook
    Réponses: 2
    Dernier message: 28/02/2014, 14h04
  2. Réponses: 11
    Dernier message: 24/09/2013, 11h06
  3. Réponses: 10
    Dernier message: 21/10/2009, 15h17
  4. [MySQL] [CMS] Gestion de Catégories/Sous catégories
    Par aenema dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 31/08/2008, 09h25
  5. Réponses: 17
    Dernier message: 07/09/2007, 08h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo