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 :

Site web portfolio dynamique


Sujet :

Schéma

  1. #21
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Bonsoir Fsmrel ,



    Citation Envoyé par fsmrel Voir le message
    et comme on traite d’ensembles finis, à un moment donné l’invité ij devra aimer un article déjà aimé par un autre invité alors que ça ne pourra pas être possible (variante de la chaise musicale...) : comme vous présumez, ça n’est pas bon et PowerAMC vous prévient.
    Hmmm d'accord je pense comprendre. Si je garde le même schéma et met une cardinalité 0.n ça résoud le problème ? On obtient la même chose qu'avec le schéma d'avant en décomposant GUEST par GUEST_LIKE, GUEST_SHARE etc (qui comportait d'ailleurs des cardinalités 1.1)


    Citation Envoyé par fsmrel Voir le message
    J’ai déjà exprimé mon point de vue dans le message #15...
    La table GUEST_LIKE sert à mémoriser le nombre de LIKE pour un article, la table GUEST_SHARE sert à mémoriser le nombre de SHARE, la table GUEST_RATE sert à mémoriser le nombre de RATE et le nombre de fois ou une note a été donnée par les utilisateurs.
    Vous avez raison, ça a juste du mal à rentrer. Comme j'ai d'autres discussions en même temps sur le sujet je reçois plein d'avis. Mais bon le niveau étant plus élevé ici je préfère redemander parfois ^^.


    Citation Envoyé par fsmrel Voir le message
    PowerAMC permet de définir les valeurs par défaut dès le MCD. En l’occurrence il suffit d'entrer « '' » dans la case qui va bien ...
    Omg fallait le savoir. Je pensais pas que c'était possible, j'aurais cherché ^^. Merci.


    Citation Envoyé par fsmrel Voir le message
    Seul l’utilisateur X peut charger les images contenues dans ses articles ? Concernant les suppressions des images, seul l’utilisateur X peut supprimer les images contenues dans ses articles ?
    Oui Seul l'auteur de l'article peut modifier ou supprimer les images contenues dans ses propres articles. C'est ce que je voulais dire par "uploader" mais vu l'association "Upload" c'était pas évident à capter ^^.

    Exception faite par contre du STAFF et de l'ADMIN qui peut faire Tout faire sur Tous les articles. "Moderate" pour moi c'est modifier, supprimer, corriger, tout en fait.


    Citation Envoyé par fsmrel Voir le message
    Mais parlons de la modification d’un article : si vous utilisez l’identification relative (cardinalités 1,1 mises entre parenthèses) :
    [MEMBRE]----0,N----(POST)----(1,1)----[ARTICLE]
    D'accord donc c'est bon ça, hourra mousaillon on y vient ^^.


    Citation Envoyé par fsmrel Voir le message
    A noter que les attributs post_date et edit_date migrent dans la table ARTICLE.
    Ils migreront ou je dois les mettre de suite dans ARTICLES au stade MCD ?
    Ne dois je pas mettre dans l'association les attributs qui justifient la création de cette même association ?


    Citation Envoyé par fsmrel Voir le message
    ...l’association DELETE doit disparaître, vous pouvez par exemple définir un sous-type ARTICLE_SUPPRIMÉ hébergeant la date de suppression, ou bien établir un lien direct entre les tables MEMBRE et ARTICLE_SUPPRIMÉ et y déménager l’article au moment de sa suppression.
    Je vote pour la 1ère solution. ARTICLES aura donc une FK USERS donc je pourrais savoir qui a écrit l'article. La question est, comment savoir qui l'a supprimé, ne dois-je pas associer USERS à l'entité sous-type ARTICLES_DELETED ?


    Voici pour le moment le résultat que je tire de vos conseils :


  2. #22
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Keizone,


    Associations SHARE_G, LIKE_G, RATE_G

    Pour récapituler, le but est de savoir, non pas quels, mais combien d’invités ont partagé et/ou aimé et/ou voté pour un article.

    Reprenons votre modélisation du 23/10/2013 (message #14). Je vous cite :
    « le guest n'est pas membre et donc absent de la BDD »
    Pourtant vous modélisez ainsi :
    [GUEST{id_guest}]----0,N---- (SHARE_G {nb_share})----0,N----[ARTICLE{id_art}]
    Alors en toute logique, au niveau de la base de données (disons SQL), la table GUEST ne peut contenir qu’une seule ligne. Si 15 invités ont partagé l’article 12, si 67 invités ont aimé cet article et si 24 invités ont partagé l’article 31, on aura la représentation tabulaire correspondante suivante (clés primaires soulignées) :
    GUEST (id_guest)             SHARE_G (id_guest, id_art, nb_share)        ARTICLE (id_art)
                  1                              1      12        15                      12
                  1                              1      31        24                      31
    
                                  LIKE_G (id_guest, id_art, nb_like)         
                                                 1      12       67      
    L’entité-type GUEST n’est au fond qu’une constante, id_guest ne prendra jamais que la valeur 1 (ou tout autre nombre qui aura votre faveur). En fait, cette constante n’offre strictement aucun intérêt, au contraire : il faudra définir une contrainte de table pour garantir que la table ne contiendra qu'une ligne ; il faudra établir une contrainte référentielle entre les tables SHARE_G et GUEST, pour rien...

    La conclusion s’impose : la table GUEST doit passer au fil du rasoir d’Ockham, et la représentation tabulaire devient :
                                 SHARE_G (id_art, nb_share)        ARTICLE (id_art)
                                              12        15                      12
                                              31        24                      31
    
                                  LIKE_G (id_art, nb_like)         
                                              12       67          
    Structure qui est celle obtenue à partir des MCD/MLD que j’ai proposés dans les messages #15 et rappelés dans le message #20.

    Passons à votre dernière représentation (message #21). La représentation tabulaire donne à peu près ceci :

    GUEST (id_guest, nb_like, nb_share, nb_rate, val_rate)       SHARE_G (id_guest, id_art)        ARTICLE (id_art)
                  1       67        15       0          0                        1      12                      12
                                                                                 1      31                      31
    
                                                                  LIKE_G (id_guest, id_art)        
                                                                                 1      12    
    Ainsi, on sait seulement qu’il y a eu au moins 15 (ou 24 après tout, ou encore 15+24) partages pour les articles 12 et 31, même principe pour les like...

    => Il n'est jamais mauvais d’illustrer et valider le travail de modélisation conceptuelle en cours au moyen d’une représentation tabulaire...


    La question est, comment savoir qui l'a supprimé, ne dois-je pas associer USERS à l'entité sous-type ARTICLES_DELETED ?
    Si vous procédez ainsi, vous autorisez à nouveau n’importe quel membre à supprimer (logiquement) les articles des autres. Comme vous avez précisé que seul l’auteur d’un article ou un modérateur est habilité à effectuer la suppression, vous pouvez établir une association du genre :

    [ADMIN]----0,N----(R1)----0,1----[ARTICLE_SUPPRIMÉ]


    Cas de l’association UPLOAD :

    En l’état, n’importe quel membre peur ajouter une image à un article d’un autre membre. Cette association doit disparaître puisque seul l’auteur de l’article peut y ajouter une image.


    Ils migreront ou je dois les mettre de suite dans ARTICLES au stade MCD ?
    Ne dois je pas mettre dans l'association les attributs qui justifient la création de cette même association ?
    Etant donné qu’au niveau du MLD le résultat sera le même, si vous préférez (comme moi) placer les attributs dans l’association, n’hésitez pas, quitte à faire tiquer certains merisiens.

    La FAQ Merise prend position, mais sans argumenter, sans dire pourquoi ça serait peccamineux de faire porter des propriétés dans des associations-types binaires. Je cite par ailleurs l’ouvrage de référence de Dominique Nanci et Bernard Espinasse. Ingénierie des systèmes d’information Merise Deuxième génération. Sybex 1996. :
    Toute relation binaire avec cardinalité 1,1 ne peut être porteuse de propriété. En effet, une telle propriété migre alors obligatoirement dans l’entité portant cette cardinalité 1,1.
    Il s’agit là d’un raisonnement circulaire, un argument d’autorité qui ne prouve rien, propre à instaurer un dialogue de sourds à la Fernand Raynaud... Si je pose la question : « Pourquoi donc une telle association ne pourrait-elle être porteuse de propriétés ? » Réponse : « Parce que ces propriétés doivent migrer ! »
    (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. #23
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    La représentation tabulaire donne à peu près ceci :

    GUEST (id_guest, nb_like, nb_share, nb_rate, val_rate)       SHARE_G (id_guest, id_art)        ARTICLE (id_art)
                  1       67        15       0          0                        1      12                      12
                                                                                 1      31                      31
    
                                                                  LIKE_G (id_guest, id_art)        
                                                                                 1      12    
    Ainsi, on sait seulement qu’il y a eu au moins 15 (ou 24 après tout, ou encore 15+24) partages pour les articles 12 et 31, même principe pour les like...
    Hmm je pense comprendre (j'ai bien dis je pense ^^). Avec cette représentation je voyais les chose dans le sens où on ne comptais pas l'id_guest (je ne l'ai pas mis sur mon modèle regardez). Je voulais uniquement récupérer le nombre de like, share et rate correspondant à tel ou tel article sans m'occuper de qui l'avait fait, juste an ajoutant "+1" dans les attributs de GUEST que j'aurais pu renommer en GUEST_ACTIVITY, ce renommage devrait plus vous éclairer sur ce que je voulais faire.
    Voici comment ca donnait dans mon crâne :

    GUEST (nb_like, nb_share, nb_rate, val_rate)
    ..........65        15       1          0
    etc.. jusqu'à 15 shares, 67 likes pour id_art 12 comme dans votre exemple
    
    SHARE_G (nb_share, id_art)
    ............6      12
    ............9      31
    
    LIKE_G (nb_like, id_art)        
    ...........24      3
    ...........11      12
    ...........30      15
    
    ARTICLE (id_art)
    ...........3
    ...........12
    ...........15
    ...........31
    Mais bon si vraiment on peut pas faire plus simple graphiquement (confirmez moi svp ^^) je me remet à ce qu'on avait dis plus haut, une table par activité (like, share, rate) ...
    Avec une cardinalité GUEST_LIKE [0.n] (like_g) [0.n] ARTICLES ?


    Citation Envoyé par fsmrel Voir le message
    Il n'est jamais mauvais d’illustrer et valider le travail de modélisation conceptuelle en cours au moyen d’une représentation tabulaire...
    Une bonne habitude à prendre certes...


    Citation Envoyé par fsmrel Voir le message
    Comme vous avez précisé que seul l’auteur d’un article ou un modérateur est habilité à effectuer la suppression, vous pouvez établir une association du genre :

    [ADMIN]----0,N----(R1)----0,1----[ARTICLE_SUPPRIMÉ]
    Je comprends pourquoi je ne dois pas relier USERS et ARTICLES_DELETED.
    Mais je ne vous suis pas pour la relation entre STAFF (pas admin) et ARTICLES_DELETED... dans ce cas de figure le staff (qui peut supprimer les articles) est relié à ARTICLES_DELETED, je ne comprends pas l'intérêt de cette relation en fait puisque j'ai déjà la relation "Moderate" entre STAFF et ARTICLES. "Moderate" en fait comprend plusieurs droits :
    - modification texte
    - modification ou suppression images
    - suppression article
    Cette association suffit non ? Dites moi tout.


    Citation Envoyé par fsmrel Voir le message
    Cas de l’association UPLOAD :

    En l’état, n’importe quel user ajouter une image à un article d’un autre membre. Cette association doit disparaître puisque seul l’auteur de l’article peut y ajouter une image.
    Sur le même modèle que ARTICLES_DELETED du coup donc ^^. Fait !


    Citation Envoyé par fsmrel Voir le message
    Etant donné qu’au niveau du MLD le résultat sera le même, si vous préférez (comme moi) placer les attributs dans l’association, n’hésitez pas, quitte à faire tiquer certains merisiens.
    Reçu !


    Citation Envoyé par fsmrel Voir le message
    ...
    Pour l'association "Remove" entre STAFF et IMAGES du coup je suis sensé faire comme pour ARTICLES_DELETED ? Le truc qui me chiffonne c'est que je veux que le STAFF puisse aussi supprimer les photos présentes dans la Gallery même du membre, dans "Mes Photos" par exemple, dans le profil utilisateur, pas seulement dans les articles. Ca ne pose pas de souci pratique ?


    Passons au MCD alors ^^, que pourrait il ne pas aller ? Les cardinalités à force de me creuser le cerveau à coup de pelleteuse j'y vois plus rien j'avoue :



  4. #24
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Keizone,


    Je voulais uniquement récupérer le nombre de like, share et rate correspondant à tel ou tel article sans m'occuper de qui l'avait fait, juste an ajoutant "+1" dans les attributs de GUEST que j'aurais pu renommer en GUEST_ACTIVITY, ce renommage devrait plus vous éclairer sur ce que je voulais faire.
    J’entends bien, mais l’objet GUEST_ACTIVITY ne correspond qu’à une vue et n’a donc pas à être modélisé. Considérez en effet le code SQL ci-dessous, issu des MCD/MLD que j’ai précédemment présentés (messages #15, #20) et qui suffisent :

    TABLE UTILISATEUR
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE UTILISATEUR (
       IdUser               INT                  NOT NULL,
       Nom                  VARCHAR(64)          NOT NULL,
       CONSTRAINT UTILISATEUR_PK PRIMARY KEY (IdUser)
    ) ;
     
    INSERT INTO UTILISATEUR VALUES (1, 'Raoul') ;
    INSERT INTO UTILISATEUR VALUES (2, 'Paul') ;
    INSERT INTO UTILISATEUR VALUES (3, 'Fernand') ;
    INSERT INTO UTILISATEUR VALUES (4, 'Tomate') ;
     
    SELECT '' AS UTILISATEUR, * FROM UTILISATEUR ;

    TABLE MEMBRE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE MEMBRE (
       IdUser               INT                  NOT NULL,
       CONSTRAINT MEMBRE_PK PRIMARY KEY (IdUser),
       CONSTRAINT MEMBRE_UTILISATEUR_FK FOREIGN KEY (IdUser) REFERENCES UTILISATEUR
    ) ;
     
    INSERT INTO MEMBRE VALUES (1) ;
    INSERT INTO MEMBRE VALUES (2) ;
    INSERT INTO MEMBRE VALUES (3) ; 
     
    SELECT '' AS MEMBRE, * FROM MEMBRE ;

    TABLE ARTICLE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE TABLE ARTICLE (
       IdArticle            INT                  NOT NULL,
       IdUserRedacteur      INT                  NOT NULL,
       TitreArticle         VARCHAR(64)          NOT NULL,
       CONSTRAINT ARTICLE_PK PRIMARY KEY (IdArticle),
       CONSTRAINT ARTICLE_MEMBRE_FK FOREIGN KEY (IdUserRedacteur) REFERENCES MEMBRE
    ) ; 
     
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (1, 1, 'art 1') ;
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (2, 1, 'art 2') ;
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (3, 1, 'art 3') ;
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (12, 1, 'art 12') ;
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (15, 1, 'art 15') ;
    INSERT INTO ARTICLE (IdArticle, IdUserRedacteur, TitreArticle) VALUES (31, 1, 'art 31') ;
     
    SELECT '' AS ARTICLE, * FROM ARTICLE ;

    TABLE GUEST_LIKE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE GUEST_LIKE (
       IdArticle            INT                  NOT NULL,
       NbVotes              INT                  NOT NULL,
       CONSTRAINT ARTICLE_GUEST_LIKE_PK PRIMARY KEY (IdArticle),
       CONSTRAINT ARTICLE_GUEST_LIKE_FK FOREIGN KEY (IdArticle) REFERENCES ARTICLE
    ) ;
     
    INSERT INTO GUEST_LIKE (IdArticle, NbVotes) VALUES (3, 24) ;
    INSERT INTO GUEST_LIKE (IdArticle, NbVotes) VALUES (12, 11) ;
    INSERT INTO GUEST_LIKE (IdArticle, NbVotes) VALUES (15, 30) ;
     
    SELECT '' AS GUEST_LIKE, * FROM GUEST_LIKE ;

    TABLE GUEST_SHARE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE GUEST_SHARE (
       IdArticle            INT                  NOT NULL,
       NbVotes              INT                  NOT NULL,
       CONSTRAINT ARTICLE_GUEST_SHARE_PK PRIMARY KEY (IdArticle),
       CONSTRAINT ARTICLE_GUEST_SHARE_FK FOREIGN KEY (IdArticle) REFERENCES ARTICLE
    ) ;
     
    INSERT INTO GUEST_SHARE (IdArticle, NbVotes) VALUES (12, 6) ;
    INSERT INTO GUEST_SHARE (IdArticle, NbVotes) VALUES (31, 9) ;
     
    SELECT '' AS GUEST_SHARE, * FROM GUEST_SHARE ;

    TABLE GUEST_RATE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE TABLE GUEST_RATE (
       IdArticle            INT                  NOT NULL,
       Note                 INT                  NOT NULL,
       NbVotes              INT                  NOT NULL,
       CONSTRAINT ARTICLE_GUEST_RATE_PK PRIMARY KEY (IdArticle, Note),
       CONSTRAINT ARTICLE_GUEST_RATE_FK FOREIGN KEY (IdArticle) REFERENCES ARTICLE,
       CONSTRAINT GUEST_RATE_CHK01 CHECK (Note BETWEEN 1 AND 5)
    ) ;
     
    INSERT INTO GUEST_RATE (IdArticle, Note, NbVotes) VALUES (12, 5, 4) ;
    INSERT INTO GUEST_RATE (IdArticle, Note, NbVotes) VALUES (12, 3, 2) ;
    INSERT INTO GUEST_RATE (IdArticle, Note, NbVotes) VALUES (31, 5, 9) ;
    INSERT INTO GUEST_RATE (IdArticle, Note, NbVotes) VALUES (31, 4, 1) ;
     
    SELECT '' AS GUEST_RATE, * FROM GUEST_RATE ;

    Concernant la table GUEST_RATE, j’ai supposé que les notes allaient de 1 à 5 et ajouté la contrainte correspondante (contrainte GUEST_RATE_CHK01), mais on peut l’adapter.

    Pour produire le résultat que vous avez présenté, comme je l'ai évoqué, on peut mettre une vue en œuvre (même si du reste ça n’est pas strictement nécessaire) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE VIEW GUEST_ACTIVITY (Nb_like, Nb_share, Nb_rate_1, Nb_rate_2, Nb_rate_3, Nb_rate_4, Nb_rate_5)
        AS
            SELECT (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_LIKE)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_SHARE)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 1)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 2)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 3)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 4)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 5)
    ;
    Et pour l’afficher :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '' AS GUEST_ACTIVITY, * FROM GUEST_ACTIVITY ;
    =>
    GUEST_ACTIVITY    Nb_like    Nb_share    Nb_rate_1    Nb_rate_2    Nb_rate_3    Nb_rate_4    Nb_rate_5
                           65          15            0            0            2            1           13 

    Avec cette représentation je voyais les choses dans le sens où on ne comptait pas l'id_guest (je ne l'ai pas mis sur mon modèle regardez).
    J’ai bien vu que vous aviez fait l’impasse sur l’attribut id_guest, mais du fait de l’absence d’identifiant, GUEST_LIKE, GUEST_SHARE et GUEST_RATE ne sont pas des entités-types mais des sacs pouvant contenir chacun un nombre quelconque d’entiers, à répétition qui plus est (par exemple 1 peut être présent un nombre indéfini de fois). Vous me direz qu’en rendant nb_like identifiant, 1 ne pourra être présent qu’une seul fois dans la table GUEST_LIKE, mais cela n’empêchera pas la présence de 2, 3, ..., N. Et quand bien même vous contrôleriez que les tables correspondantes ne contiendraient chacune qu’une seule ligne, alors leur contenu serait redondant (puisqu’en étant la somme) avec celui des tables issues des associations LIKE_G, SHARE_G, RATE_G, ce que prouve la vue GUEST_ACTIVITY définie ci-dessus.


    "Moderate" en fait comprend plusieurs droits :
    - modification texte
    - modification ou suppression images
    - suppression article
    Puisque MODERATE sert pour la suppression d’un article, alors ARTICLE_DELETED fait double emploi, redonde, donc disparaît. En contrepartie, MODERATE devra être dotée d’un attribut permettant de connaître la nature de l’opération qu’un article a subie, suppression logique en l’occurrence.


    Passons au MCD alors ^^, que pourrait il ne pas aller ?
    Pour la partie GUEST, mettez en œuvre ce que je vous ai proposé en #15. Pour le mode d’emploi au sujet de l’identification relative, je rappelle que ça se passe ici.

    Remarque : les invités ayant disparu, si les utilisateurs sont désormais tous membres, alors les entités-types USER et MEMBRE ne font qu’une, l’une absorbe l’autre.
    (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. #25
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Bonjour Fsmrel ^^,



    On va prendre un abonnement bientôt .

    Citation Envoyé par fsmrel Voir le message
    Considérez en effet le code SQL ci-dessous, issu des MCD/MLD que j’ai précédemment présentés (#20) et qui suffisent...
    J'ai bien le jeu de code . Je me devais de le préciser vu le travail et vue que j'ai "rien à y redire", façon de parler.


    Citation Envoyé par fsmrel Voir le message
    ...j’ai supposé que les notes allaient de 1 à 5 et ajouté la contrainte GUEST_RATE_CHK01...
    Vous avez très bien supposé . Il n'y a qu'à modifier l'intervalle (between) au pire. Par contre pour éviter de le coder derrière, peut on préciser cet intervalle au niveau MCD grâce aux valeurs "minimum = 1" et maximum = 5" dans "Contrôle standard" en right clic sur l'attribut "valor" ? Cela suffit ?


    Citation Envoyé par fsmrel Voir le message
    Pour produire le résultat que vous avez présenté, on peut mettre une vue en œuvre (même si ça n’est pas strictement nécessaire) :...
    Bon je ne maîtrisais pas la différence entre la Table et la Vue. Après avoir cherché ma réponse (= Bonjour Fsmrel ^^,



    On va prendre un abonnement bientôt .

    Citation Envoyé par fsmrel Voir le message
    Considérez en effet le code SQL ci-dessous, issu des MCD/MLD que j’ai précédemment présentés (#20) et qui suffisent...
    J'ai bien le jeu de code . Je me devais de le préciser vu le travail et vue que j'ai "rien à y redire", façon de parler.


    Citation Envoyé par fsmrel Voir le message
    ...j’ai supposé que les notes allaient de 1 à 5 et ajouté la contrainte GUEST_RATE_CHK01...
    Vous avez très bien supposé . Il n'y a qu'à modifier l'intervalle (between) au pire. Par contre pour éviter de le coder derrière, peut on préciser cet intervalle au niveau MCD grâce aux valeurs "minimum = 1" et maximum = 5" dans "Contrôle standard" en right clic sur l'attribut "valor" ? Cela suffit ?


    Citation Envoyé par fsmrel Voir le message
    Pour produire le résultat que vous avez présenté, on peut mettre une vue en œuvre (même si ça n’est pas strictement nécessaire) :...
    Bon je ne maîtrisais pas la différence entre la Table et la Vue. Après avoir cherché, je comprends pas votre partie sur mon modèle avec GUEST_ACTIVITY, ni ce que vous voulez me faire rentrer dans le crâne en fait ^^. Pour votre modèle aussi on pourrait avoir une vue si on voulait, il n'y a pas plus d'identifiant il me semble ni de PK (j'ai cherché un aussi la différence entre les deux). Je ne parviens pas à voir la différence entre nos 2 idées surtout concernant la redondance, éclairez ma lanterne please . En fait tout ce que je vois basiquement c'est une différence graphique, je rassemble, vous décomposez. Je sais je sais, je comprends vite mais il faut m'expliquer longtemps ...


    Citation Envoyé par fsmrel Voir le message
    Si MODERATE sert pour la suppression d’un article, alors ARTICLE_DELETED fait double emploi, redonde, donc disparaît. En contrepartie, MODERATE devra être dotée d’un attribut permettant de connaître la nature de l’opération qu’un article a subie, suppression logique en l’occurrence.
    Il redonde pour le cas où un membre du STAFF supprime l'article mais pas pour le cas où un membre classique supprime son propre article non ? Du coup cela justifie t-il de le laisser la table ARTICLES_DELETED ??

    J'ai ajouté 3 booléens dans Moderate :
    - edit_case =
    CAS où la nature de la modération est une modification texte.
    - img_delete_case =
    CAS où la nature de la modération est une suppression d'image d'un article.
    - art_delete_case =
    CAS où la nature de la modération est une suppression d'article.

    Du coup pour le cas "art_delete_case", ARTICLES_DELETED manque non ? Le but de cette dernière table est de répertorier les articles supprimés afin de savoir quand et qui a fait l'opération.


    Citation Envoyé par fsmrel Voir le message
    Pour la partie GUEST, mettez en œuvre ce que je vous ai proposé en #15.
    C'est fait, je vous laisse regarder plus bas. Exception faite de la cardinalité entre l'asso' de GUEST_SHARE et ARTICLES. Un article peut être partagé 0 ou plein de fois, pas seulement une fois (Partage Facebook).

    Pour GUEST_LIKE par contre petite aparté, je souhaite qu'on puisse dislike[r] (ne plus aimer) tel ou telle article ou commentaire qu'on a lik[é] auparavant. J'imagine que pour ça je dois rajouter un attribut booléen type "like_status" (état du like) puis ensuite manier jQuery à l'SQL du style :
    - Au clic (event jQuery), update la valeur "like_status" de 1 à 0. J'ai bon ?!


    Citation Envoyé par fsmrel Voir le message
    Pour la partie GUEST, mettez en œuvre ce que je vous ai proposé en #15.
    En effet oui ! Voilà qui es fait (plus bas).


    MCD ? :


  6. #26
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Keizone,


    Il n'y a qu'à modifier l'intervalle (between) au pire. Par contre pour éviter de le coder derrière, peut on préciser cet intervalle au niveau MCD grâce aux valeurs "minimum = 1" et maximum = 5" dans "Contrôle standard" en right clic sur l'attribut "valor" ? Cela suffit ?
    Oui. Pour vous en convaincre, faites-le au stade MCD, générez le MPD, et générez la base de données, la table GUEST_RATE contiendra la contrainte, comme dans mon message précédent :

    TABLE GUEST_RATE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE GUEST_RATE (
       IdArticle            INT                  NOT NULL,
       Note                 INT                  NOT NULL,
       NbVotes              INT                  NOT NULL,
       CONSTRAINT ARTICLE_GUEST_RATE_PK PRIMARY KEY (IdArticle, Note),
       CONSTRAINT ARTICLE_GUEST_RATE_FK FOREIGN KEY (IdArticle) REFERENCES ARTICLE,
       CONSTRAINT GUEST_RATE_CHK01 CHECK (Note BETWEEN 1 AND 5)
    ) ;

    je comprends pas votre partie sur mon modèle avec GUEST_ACTIVITY, ni ce que vous voulez me faire rentrer dans le crâne en fait ^^
    GUEST_ACTIVITY n’est que le nom que j’ai donné à une expression relationnelle afin que, si l’on a besoin de manipuler cette expression, ça soit sous la forme d’une table, de façon simple, sans avoir à chaque fois à coder :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            SELECT (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_LIKE)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_SHARE)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 1)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 2)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 3)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 4)
                 , (SELECT COALESCE(SUM(NbVotes), 0) FROM GUEST_RATE WHERE Note = 5) ;

    La structure de l’en-tête de cette table virtuelle est celle d’une table de base :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    GUEST_ACTIVITY (Nb_like, Nb_share, Nb_rate_1, Nb_rate_2, Nb_rate_3, Nb_rate_4, Nb_rate_5)
    Mais l’utilisateur n’a pas conscience de ce qu’il y a sous le capot.

    Cette vue ne fait pas partie du niveau conceptuel merisien, mais du niveau relationnel. Ce que j’ai voulu vous faire rentrer dans le crâne c’est que l’entité-type GUEST que vous aviez définie contiendrait « en dur » des données que l’on sait calculer au moyen de la requête à laquelle j’ai donné le nom GUEST_ACTIVITY :

    GUEST (nb_like, nb_share, nb_rate, val_rate)
    ..........65        15       1          0
    etc.. jusqu'à 15 shares, 67 likes pour id_art 12 comme dans votre exemple
    
    SHARE_G (nb_share, id_art)
    ............6      12
    ............9      31
    
    LIKE_G (nb_like, id_art)        
    ...........24      3
    ...........11      12
    ...........30      15
    
    ARTICLE (id_art)
    ...........3
    ...........12
    ...........15
    ...........31 
    Mais vu votre scepticisme, il fallait que je vous prouve que votre entité-type GUEST était redondante et ne devait donc pas être modélisée puisque la redondance est un ennemi des bases de données.


    Pour votre modèle aussi on pourrait avoir une vue si on voulait
    Alors prouvez-le, chacun son tour.


    il n'y a pas plus d'identifiant il me semble ni de PK (j'ai cherché un aussi la différence entre les deux). Je ne parviens pas à voir la différence entre nos 2 idées surtout concernant la redondance, éclairez ma lanterne please
    Je vous renvoie à ce que j’ai écrit dans le message #18 :

    Citation Envoyé par fsmrel
    [...]du fait de l’identification relative (symbolisée par la mise entre parenthèses de la cardinalité 1,1), l’entité-type GUEST_LIKE hérite automatiquement de l’identifiant de l’entité-type ARTICLE, sans pour autant que cet identifiant hérité ait besoin d’être mentionné pour l’héritière.
    On voit ci-dessous l’utilisation de l’identification relative (cf. mon message #15) et sa non utilisation, comme dans votre MCD :




    En conséquence de l’identification relative, PowerAMC définit les clés primaires nécessaires pour les tables lors da la production du MLD à partir du MCD. En l’absence d’identification relative, PowerAMC ne génère pas de clés, les tables sont des sacs, c’est affreux, affreux :






    En effet oui ! Voilà qui est fait (plus bas).
    Ben non si on se réfère à ce qui précède...


    Concernant la différence entre identifiant et clé :

    L’identifiant appartient au vocabulaire de Merise et a une connotation sémantique. A noter que dans le contexte de Merise, de façon un peu trop rapide, on dit que chaque entité d’entité-type est identifiée au moyen d’une propriété particulière (par exemple ArticleId pour l’entité-type ARTICLE). Pour sa part le grand Yves Tabourier rappelle que les propriétés d’une entité-type ont pour objet de décrire cette entité-type, tandis que l’identifiant ne décrit rien : « Son rôle fondamental est d’être sur de distinguer deux jumeaux parfaits, malgré des descriptions identiques » (De l’autre côté de Merise, page 80).

    Ce qui précède est caractéristique de l’identification absolue. Par contraste, l’identification relative fait participer l’identifiant d’une entité-type considérée comme « forte » (par exemple ARTICLE) à l’identifiant d’une entité-type considérée comme « faible » (par exemple GUEST_LIKE) via l’association qui les unit.

    La clé candidate de la théorie relationnelle n’est pas à appréhender selon une vision sémantique voire psychologique, mais mathématique, dépourvue de charge émotionnelle. J’en rappelle la définition :
    Une clé candidate (clé pour abréger) est un sous-ensemble d’attributs K de l’en-tête d’une relvar R, respectant les deux contraintes suivantes :
    Unicité. Deux tuples distincts de R ne peuvent avoir simultanément même valeur de K.
    Irréductibilité (ou minimalité). Il n’existe pas de sous-ensemble strict de K garantissant la règle d’unicité.
    La clé primaire est une clé candidate que l’on a élue comme telle parmi l’ensemble des clés candidates, sur des critères tels que son invariance, son absence de signification (là on rejoint Tabourier).


    Il redonde pour le cas où un membre du STAFF supprime l'article mais pas pour le cas où un membre classique supprime son propre article non ?
    Il est un fait que si le rédacteur de l’article peut en effectuer la suppression logique, alors l’entité-type ARTICLE_DELETED est justifiée et doit être conservée.


    J'ai ajouté 3 booléens dans Moderate :
    - edit_case =
    CAS où la nature de la modération est une modification texte.
    - img_delete_case =
    CAS où la nature de la modération est une suppression d'image d'un article.
    - art_delete_case =
    CAS où la nature de la modération est une suppression d'article.
    Les 3 booléens peuvent prendre la valeur « vrai » en même temps : qu’un acte de modération soit à la fois une modification de texte et une suppression de texte est contradictoire : prévoir un seul type de modération à l’instant T.

    Par ailleurs, comme vous avez modélisé ainsi :
    [STAFF]----0,N----(MODERATE)----0,N----[ARTICLE]
    Alors le modérateur S1 ne pourra modérer qu’une seule fois l’article A1.


    Pour GUEST_LIKE par contre petite aparté, je souhaite qu'on puisse dislike[r] (ne plus aimer) tel ou telle article ou commentaire qu'on a lik[é] auparavant.
    Dans la mesure où l’attribut nb_like de l’entité-type GUEST_LIKE est incrémenté d’une unité à chaque like, en toute logique il est à décrémenter d’autant lors d’un dislike.
    (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. #27
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Bonjour Fsmrel ,



    Citation Envoyé par fsmrel Voir le message
    Oui. Pour vous en convaincre, faites-le au stade MCD, générez le MPD, et générez la base de données, la table GUEST_RATE contiendra la contrainte, comme dans mon message précédent : ...
    Ca marche oui. De ce fait j'envisage de préciser la valeur par défaut de tous les attributs de toutes mes entités à part les password et champs mail par exemple. J'ai déduis que je devais faire ça pour avoir mes valeurs par défauts partout et gérer l'absence du "NULL". En ne le faisant pas je risque d'avoir des soucis sur les champs facultatifs Non Remplis d'un formulaire mais pourtant Obligatoire au niveau relationnel. Si j'ai bien compris toujours...

    Par contre pour les attributs de type texte, est ce qu'un espace suffit ?

    Pour les attributs de type Date&heure que dois mettre ? Sachant que j'utiliserai MySQL. Sybase me parle des formats mais je pense pas qu'il pense aux spec MySQL.

    Comment ca se passe pour les INT dont on veut limiter la taille à 14 chiffres (n° SIRET par exemple). J'ai bien un champ "longueur" et "précision" mais non fonctionnels... Sybase est très... trop complète sur le sujet, ce que je cherche doit être noyé dans un flot infini d'infos...

    Pour les booléens, si je souhaitais que l'attribut soit FALSE par défaut. Si je met "FALSE" dans "Contrôle standart / Défaut", ce sera un "FALSE" booléen ou une simple string ??

    Je sais que ces questions sont simplistes mais je découvre un pan de PowerAMC qui peut faciliter la vie et j'ai bien l'intention de m'en servir pour me faciliter la vie niveau code pour la suite... Par contre comme après je compte basculer sur MySQLWorkbench je me demande si ce ne serait pas mieux que je gère ces détails sur le soft en question et pas sur PowerAMC à la limite...


    Citation Envoyé par fsmrel Voir le message
    Mais vu votre scepticisme, il fallait que je vous prouve que votre entité-type GUEST était redondante et ne devait pas être modélisée puisque la redondance est un ennemi...
    ...
    Alors prouvez-le, chacun son tour.
    Ola je ne prendrai pas de risque sur ce coup . Mais d'après ce que je lis concernant les vues (http://fr.wikipedia.org/wiki/Vue_%28...onn%C3%A9es%29), il est possible d'en faire pour n'importe quelle table, d'où mon interrogation à vrai dire...


    Citation Envoyé par fsmrel Voir le message
    On voit ci-dessous l’utilisation de l’identification relative (cf. mon message #15) et sa non utilisation, comme dans votre MCD : ...
    Ah ok les parenthèses donc... Je pensais que la cardinalité "1.1" suffisait pour faire comprendre au soft' l'identification relative. La question est comment je la matérialise sur PAMC ? Il ne veut pas des parenthèses... Y a bien un onglet "Dépendance" mais je ne vois rien graphiquement.


    Citation Envoyé par fsmrel Voir le message
    ...qu’un acte de modération soit à la fois une modification de texte et une suppression de texte est contradictoire : prévoir un seul type de modération à l’instant T.
    Hmm je comprends pas. Une suppression texte Est une modification texte, par définition et vice versa. Pourquoi est-ce contradictoire ?

    La modification de la valeur du type de modération à l'instant T ne se fait-il pas au moment ou la personne clique sur "Valider" juste après modération pour valider le message modifié ??

    Si je n'ai qu'un seul type de modération, je (moi l'admin) ne pourrais pas savoir si le Staff a fait par exemple une modification texte ou suppression image non ??


    Citation Envoyé par fsmrel Voir le message
    Par ailleurs, comme vous avez modélisé ainsi :
    [STAFF]----0,N----(MODERATE)----0,N----[ARTICLE]
    Alors le modérateur S1 ne pourra modérer qu’une seule fois l’article A1.
    Ah bon ?!
    Le Staff peut modérer "0" ou "n" fois,
    un article peut être modéré "0" ou "n" fois.
    Je comprends pas pourquoi il ne pourrait le faire qu'une seule fois ...



    Merci d'avance .

  8. #28
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Keizone,


    Ca marche oui. De ce fait j'envisage de préciser la valeur par défaut de tous les attributs de toutes mes entités à part les password et champs mail par exemple. J'ai déduis que je devais faire ça pour avoir mes valeurs par défauts partout et gérer l'absence du "NULL".
    Vous pouvez effectivement généraliser le principe de définition de la valeur par défaut pour chaque attribut. En tout cas, l’essentiel est de préciser NOT NULL systématiquement.


    Pour les attributs de type texte, est ce qu'un espace suffit ?
    Oui, ou simplement une chaîne vide.


    Pour les attributs de type Date&heure que dois mettre ?
    Prenons le cas de l’attribut birth_date, lequel permet de connaître la date de naissance d’un utilisateur. Selon la norme SQL, une date est valide dans un intervalle allant du 1er janvier de l’an 1 de l’ère chrétienne ('0001-01-01') au 31 décembre 9999 ('9999-12-31'), tout en sachant que certains SGBD ne respectent pas cette convention : dans le cas de MySQL, voyez la documentation correspondant à la version que vous utilisez. Quoi qu’il en soit, de ce que j’en ai lu, vous pouvez utiliser '0000-00-00' comme valeur par défaut et signifier ainsi que la date de naissance n’a pas été fournie par l’utilisateur.


    Comment ca se passe pour les INT dont on veut limiter la taille à 14 chiffres (n° SIRET par exemple).
    Personnellement je ne considère pas le n° SIRET comme un nombre, car la somme de deux SIRET n’a pas de sens, tout comme plus généralement les opérations arithmétiques ayant des SIRET pour opérandes ou encore la comparaison de deux SIRET. En outre, tous les SIRET ne sont pas astreints à avoir une structure numérique si j’en crois Wikipedia :
    « Le SIRET n'est pas systématiquement un nombre entier positif de 14 chiffres : Pour certaines zones géographiques comme Monaco, il peut être aussi une suite de caractères alphanumériques, comme par exemple : MONACOCONFO001 »
    Cela dit, quand j’utilise un SGBD comme DB2 ou SQL Server, j’ai l’habitude de représenter ainsi l’attribut SIRET :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE UTILISATEUR
    ...
          , SIRET                CHAR(14)             NOT NULL   DEFAULT ''
    ...
        , CONSTRAINT UTILISATEUR_CHK_SIRET CHECK (ISNUMERIC(SIRET) OR SIRET = '') 
    ...
    (je ne m’intéresse pas à Monaco, mais au besoin ça ne poserait pas de problème, en complétant la contrainte en conséquence).

    Le problème avec MySQL est que, s’il accepte que l’on code la contrainte UTILISATEUR_CHK_SIRET, en revanche il n’assure aucun contrôle ! (MySQL 5.6 Reference Manual) :
    « The CHECK clause is parsed but ignored by all storage engines »
    Il vous reste vos yeux pour pleurer, ou réagir en programmant un trigger garantissant la contrainte UTILISATEUR_CHK_SIRET.


    Pour les booléens, si je souhaitais que l'attribut soit FALSE par défaut. Si je met "FALSE" dans "Contrôle standard / Défaut", ce sera un "FALSE" booléen ou une simple string ??
    A nouveau, vous pouvez tester vous-même ce que cela donne, je parie néanmoins une poignée de main contre une poignée de porte que cela donnera :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
       ColonneX     BOOL    NOT NULL   DEFAULT FALSE

    Je sais que ces questions sont simplistes mais je découvre un pan de PowerAMC qui peut faciliter la vie et j'ai bien l'intention de m'en servir pour me faciliter la vie niveau code pour la suite...
    Certes, sans oublier que MySQL méprise superbement la contrainte CHECK...


    Par contre comme après je compte basculer sur MySQL Workbench je me demande si ce ne serait pas mieux que je gère ces détails sur le soft en question et pas sur PowerAMC à la limite...
    C’est comme vous voulez. Vous pouvez définir les valeurs par défaut avec PowerAMC et les récupérer par rétro-conception, ou les définir nativement avec Workbench...


    Mais d'après ce que je lis concernant les vues (http://fr.wikipedia.org/wiki/Vue_%28...onn%C3%A9es%29), il est possible d'en faire pour n'importe quelle table, d'où mon interrogation à vrai dire...
    On peut définit des vues à partir de tables de base et/ou vues, mais au départ il faut des tables de base, ce que sont GUEST_LIKE, GUEST_SHARE et GUEST_RATE : il n’y a pas de génération spontanée, sans ces tables pour amorcer la pompe vous ne pourrez définir aucune vue.


    Ah ok les parenthèses donc... Je pensais que la cardinalité "1.1" suffisait pour faire comprendre au soft' l'identification relative. La question est comment je la matérialise sur PAMC ? Il ne veut pas des parenthèses... Y a bien un onglet "Dépendance" mais je ne vois rien graphiquement.
    Vous devriez suivre les liens que je m’évertue à vous fournir, message après message : voici l’image à laquelle je vous renvoie en permanence et qui aurait dû vous crever les yeux...




    Une suppression texte Est une modification texte, par définition et vice versa. Pourquoi est-ce contradictoire ?
    En français une suppression de quelque chose n’en est pas la modification (reportez-vous à un dictionnaire). C’est comme pour une voiture, soit on la détruit, soit on la répare, mais pas les deux à la fois... Même SQL propose une instruction pour modifier une ligne (UPDATE) et une autre instruction pour supprimer une ligne (DELETE). Si aussi curieux que cela paraisse, pour vous c’est la même chose, alors dans MODERATE il y a (au moins) un booléen redondant qui doit donc disparaître.


    Si je n'ai qu'un seul type de modération, je (moi l'admin) ne pourrais pas savoir si le Staff a fait par exemple une modification texte ou suppression image non ??
    Remarque non recevable. Si vous supprimez (logiquement) une image, c’est l’association REMOVE connectant les entités-types STAFF et IMAGE qui permet de prendre en compte la suppression de cette image. L’association MODERATE connecte l’entité-type STAFF non pas avec une image mais avec un article. Le booléen restant permet de savoir si un article est resté intègre ou a été modifié par un modérateur.


    Ah bon ?!
    Le Staff peut modérer "0" ou "n" fois,
    un article peut être modéré "0" ou "n" fois.
    Je ne comprends pas pourquoi il ne pourrait le faire qu'une seule fois.
    Disons que la règle que vous énoncez est ambiguë. Partons de la traduction au niveau SQL de l’association MODERATE qui par définition est la suivante :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE MODERATE
    (
            Id_user         INT       NOT NULL,
            Id_article      INT       NOT NULL,
            Moderate_date   INT       NOT NULL,
    ...
            PRIMARY KEY (Id_user, Id_article)
     
    ) ;
    Si une 1re fois le modérateur U1 modère l’article A1 à la date D1, on aura droit qu’une seule fois au triplet de valeurs : <U1, A1, D1>. Il sera possible de remplacer ce triplet par le suivant : <U1, A1, D2>, mais impossible d’avoir ces deux triplets présents en même temps dans la table : en effet, puisque la paire {Id_user, Id_article} est clé de la table, on a droit qu’à une seule occurrence de <U1, A1>.
    (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.

  9. #29
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Bonjour Fsmrel , toujours fidèle au rendez vous,



    Citation Envoyé par fsmrel Voir le message
    ...
    Merci pour les infos sur les types, j'ai appliqué .
    Notamment pour le SIRET, en effet c'est quelque chose que j'ai appris mais oublié ^^. Pour le moment je vais me limiter à lui attribuer le type CHAR limité à 14. On peut mettre des chiffres dans une string donc ça ira j'imagine. Le problème est donc l'aspect sécurité ou contrôle de ce que les gens rentrent si je vous suis bien.

    Pour le booléen la valeur 0 semble signifie FALSE par convention :
    - http://www.developpez.net/forums/d51...boolean-mysql/
    - http://dev.mysql.com/doc/refman/5.0/...-overview.html



    Citation Envoyé par fsmrel Voir le message
    C’est comme vous voulez. Vous pouvez définir les valeurs par défaut avec PowerAMC et les récupérer par rétro-conception, ou les définir nativement avec Workbench...
    Hmmm io non ho capito mio amico . Me dites vous que je peux importer facilement mon modèle de PowerAMC à MySQL Workbench ? Ou du moins quelques paramètres ?? Ca m'intéresse plus que fortement si c'est le cas, m'éviterai de tout refaire alla mano.

    Nativement dans Workbench soit définir les valeurs par défaut dans les paramètres des modèles ? Hmm pas bête ça, ça évite de les faire un par un comme j'ai fait sur PAMC.


    Citation Envoyé par fsmrel Voir le message
    ...voici l’image à laquelle je vous renvoie en permanence et qui aurait dû vous crever les yeux..

    Hmmm d'accord. Voilà qui est fait, l'identification relative du côté d'ARTICLES. J'ai donc aussi modifié les cardinalités du côté GUEST_XXX, ca devrait être bon là à priori.


    Citation Envoyé par fsmrel Voir le message
    En français une suppression de quelque chose n’en est pas la modification (reportez-vous à un dictionnaire). Même SQL propose une instruction pour modifier une ligne (UPDATE) et une autre instruction pour supprimer une ligne (DELETE). Si aussi curieux que cela paraisse, pour vous c’est la même chose, alors dans MODERATE il y a (au moins) un booléen redondant qui doit donc disparaître.
    En fait je fais la distinction entre :
    - Supprimer Une ligne d'un paragraphe présent dans un article = txt_edit_case
    et
    - Supprimer Tout le texte d'un article = delete_case
    puis
    - Supprimer Une image d'un article contenant aussi du texte = img_edit_case
    (sachant que ces 3 cas font partie de la modération, entité-type "Moderate")

    Vous voyez ce que je veux dire ? C'est pour cela que je considère que supprimer une ligne d'un paragraphe n'est pas un cas SQL "delete". J'ai pas faux quand même si ? Doit-on vraiment appliquer une instruction "delete" si on ne vire qu'un mot d'une phrase d'un article ???
    M'enfin ceci dit j'ai simplifié en ne gardant que le cas edit et delete.


    Citation Envoyé par fsmrel Voir le message
    Remarque non recevable. Si vous supprimez une image, c’est l’asso' REMOVE entre STAFF et IMAGE qui permet de prendre en compte la suppression de l'image. L’association MODERATE connecte l’entité-type STAFF non pas avec une image mais avec un article.
    Oh oui, autant pour moi. Hmm est-il utile d'ajouter une table IMAGES_DELETED du coup ? Afin de conserver les images supprimées en base en attendant que je décide de purger, puis pour me permettre d'apposer si besoin une seconde modération type ""remettre cette image en ligne car je ne suis pas d'accord avec la décision du modérateur qui l'a supprimée"".
    On en a déjà parlé il me semble, je me sens amnésique par fois . J'ai modélisé l'idée sur le MCD à jour en bas de ce post.


    Citation Envoyé par fsmrel Voir le message
    Disons que la règle que vous énoncez est ambiguë. Partons de la traduction au niveau SQL de l’association MODERATE qui par définition est la suivante :

    Si une 1re fois le modérateur U1 modère l’article A1 à la date D1, on aura droit qu’une seule fois au triplet de valeurs : <U1, A1, D1>. Il sera possible de remplacer ce triplet par le suivant : <U1, A1, D2>, mais impossible d’avoir ces deux triplets présents en même temps dans la table...
    Hmm d'accord. J'ai du mal avec ça, parce que du coup je vois la même chose partout. Du coup c'est le même délire entre Associate et ARTICLES non ? Je dois passer ma cardinalité de l'actuel "0,n" à "0,1" ?


    ↓↓ MCD ↓↓ :



  10. #30
    Membre à l'essai
    Homme Profil pro
    Mécanicien / Infographiste / Développeur en formation
    Inscrit en
    Octobre 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Mécanicien / Infographiste / Développeur en formation

    Informations forums :
    Inscription : Octobre 2012
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Up camarades . Wake up guys ^^. Il n'y en a pas qu'un qui sait ces choses là quand même .

  11. #31
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour Keizone,


    Le problème est donc l'aspect sécurité ou contrôle de ce que les gens rentrent si je vous suis bien.
    Les utilisateurs de bonne volonté, mais disons distraits, sont capables de rentrer n’importe quoi, en conséquence de quoi, comme on le répète depuis les origines, c’est à vous d’assurer à tout coup de vérifier systématiquement que ce qu’ils fournissent est correct : comme je l’ai déjà écrit, contrairement à la norme et aux autres SGBD, MySQL ne propose pas la clause CHECK en relation avec l’instruction CREATE TABLE, d’où des palliatifs du genre trigger. En poussant le bouchon jusqu’a bout, vous pourriez vérifier la validité du SIRET). Cela vaut aussi pour les contraintes du genre : CONSTRAINT GUEST_RATE_CHK01 CHECK (Note BETWEEN 1 AND 5), cf. message #24.


    dites vous que je peux importer facilement mon modèle de PowerAMC à MySQL Workbench ?
    Votre MCD n’est évidemment pas directement exportable vers MWB (MySQL Workbench), ne serait-ce que parce que PowerAMC est né quelques années avant MySQL, donc avant MWB et d’autre part parce que PowerAMC se situe au niveau conceptuel (celui des entités-types), un cran au-dessus du niveau logico-physique SQL auquel se situe MWB (tables, index). Pour exporter, il faut donc d’abord demander à PowerAMC de produire un MLD à partir du MCD, ou plutôt un MPD car vous pouvez alors demander la génération du code SQL de création des tables, et à son tour MWB permet de faire de la rétroconception à partir de ce code (y-compris pour les valeurs par défaut, mais pas pour les contraintes CHECK puisque MYSQL les ignore, hélas !).


    J'ai donc aussi modifié les cardinalités du côté GUEST_XXX, ca devrait être bon là a priori.
    Petit problème, car tel Dagobert vous avez fait ça à l’envers...
    Autrement dit, entre autres erreurs, vous avez fait d’ARTICLE une association entre GUEST_LIKE, GUEST_SHARE, GUEST_RATE.
    En effet, au vu des cardinalités, cela vous a peut-être échappé, mais le sens de lecture des associations que vous avez établies est le suivant (copropriété d'un article) :
    Un article est la propriété d’un GUEST_LIKE ;

    Cet article est la propriété d’un GUEST_SHARE ;

    Cet article est la propriété d’un GUEST_RATE ;

    Un GUEST_LIKE peut-être facultativement composé d’un article (et un seul) ;

    Un GUEST_SHARE peut-être composé de 0 à N articles ;

    Un GUEST_RATE peut-être composé de 0 à N articles.
    Vous reconnaîtrez que tout est à l’envers...

    Conformément aux diagrammes que je vous ai fournis depuis un bon moment, il faut rétablir la situation ainsi :

    [ARTICLE]----0,1----( )----(1,1)----[GUEST_LIKE]

    [ARTICLE]----0,1----( )----(1,1)----[GUEST_SHARE]

    [ARTICLE]----0,N----( )----(1,1)----[GUEST_RATE]


    En fait je fais la distinction entre :
    - Supprimer Une ligne d'un paragraphe présent dans un article = txt_edit_case
    et
    - Supprimer Tout le texte d'un article = delete_case
    puis
    - Supprimer Une image d'un article contenant aussi du texte = img_edit_case
    (sachant que ces 3 cas font partie de la modération, entité-type "Moderate")
    Qu’un modérateur puisse supprimer tout le texte d’un article ou une partie du texte d’un article ou bien une image, c’est évidemment la moindre des choses, mais la modélisation que vous avez faite de ces actions n’est pas bonne. En effet, si par exemple vous supprimez tout le texte d’un article, il est pour le moins maladroit de dire qu’en même temps on peut en supprimer une partie...

    Concernant la suppression d’une image par un modérateur, je répète ce que j’ai déjà écrit :
    Citation Envoyé par fsmrel
    Si vous supprimez (logiquement) une image, c’est l’association REMOVE connectant les entités-types STAFF et IMAGE qui permet de prendre en compte la suppression de cette image. L’association MODERATE connecte l’entité-type STAFF non pas avec une image mais avec un article.
    L’association MODERATE ne concerne donc que la modification du texte d’un article ou la suppression (logique) de l’article. Cette association est donc porteuse d’un attribut, appelons-le par exemple STATUT qui peut prendre trois valeurs : 0 (article ni modifié ni supprimé), 1 (article modifié), 2 (article supprimé logiquement). Je répète une fois de plus qu’avec vos deux booléens edit_case, delete_case, vous permettez qu’un article soit en même temps modifié et supprimé, ce qui est absurde.


    est-il utile d'ajouter une table IMAGES_DELETED du coup ?
    L’entité-type IMAGE_DELETED n’est à conserver que si c’est l’auteur de l’article qui a supprimé une image et que vous vouliez garder la trace de l’opération.


    Du coup c'est le même délire entre Associate et ARTICLES non ? Je dois passer ma cardinalité de l'actuel "0,n" à "0,1" ?
    Il faudrait que vous étudiez sérieusement les bases de la modélisation des cardinalité des associations. Quand vous modélisez :
    [STAFF]----0,N----(MODERATE)----0,1----[ARTICLE]
    Cela veut dire qu’un article ne peut être modéré que par un seul modérateur.

    Par exemple, l’article A1 a été modéré par U1 à la date D1. En vertu des vos cardinalités, on peut effectuer une mise à jour de la table en remplaçant le triplet <A1, U1, D1> par celui-ci : <A1, U2, D1> ou celui-là : <A1, U2, D2> ou encore : <A1, U1, D2>, mais on aura procédé par « annule et remplace ».

    A contrario, quand vous modélisez :
    [STAFF]----0,N----(MODERATE)----0,N----[ARTICLE]
    Cela veut dire qu’un article peut être modéré par plusieurs modérateurs.

    Au niveau SQL :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE MODERATE
    (
            Id_user         INT       NOT NULL,
            Id_article      INT       NOT NULL,
            Moderate_time   DATETIME  NOT NULL,
    ...
            PRIMARY KEY (Id_user, Id_article)
     
    ) ;

    Selon la clé primaire, on ne peut pas garder le suivi de chacune des modérations effectuées par U1 de l’article A1, mais seulement la trace de sa dernière modération, ainsi que la trace de la dernière modération faite par U2.

    La table MODERATE peut contenir en même temps les triplets <A1, U1, Di> et <A1, U2, Dj>, <A2, U1, Dk>, etc., car en l’occurrence il n’y a pas de doublons de la clé (Id_user, Id_article). En revanche, une paire comme <A1,U1> ne peut pas être présente plus d’une fois. Autrement dit, si la règle est la suivante :
    On doit pouvoir conserver la trace de chaque modération de l’article A1 effectuée par U1, U2, ..., Un.

    Alors au niveau SQL la structure sera la suivante :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE MODERATE
    (
            Id_user         INT       NOT NULL,
            Id_article      INT       NOT NULL,
            Moderate_time   DATETIME  NOT NULL,
    ...
            PRIMARY KEY (Id_article, Moderate_time)
     
    ) ;
    La seule contrainte étant par conséquent que deux modérateurs ne peuvent pas modérer en même temps le même article. Dans ces conditions, on modélise ainsi au niveau MCD :




    La flèche rouge symbolise ce qu’en Merise on appelle une CIF (contrainte d’intégrité fonctionnelle), selon laquelle à une date donnée (ou plus finement à un instant donné) un article n’a pu être modéré que par un seul modérateur.

    Le problème est que PowerAMC ne connaît pas le concept de CIF... Pour cette raison et un tas d’autres : prise en compte des votes des invités, etc., je vous propose de passer dès maintenant à MySQL Workbench, et vous aurez peut-être une vision objective de ce que sera la structure de votre base de données. Traduction de la CIF en Workbench :


    Notez la différence entre la notation Merise (inconnue de MWB) et la notation UML disponible avec MWB.


    Je note que vous avez défini des attributs nb_like_m, nb_share_m et nb_rate_m dans l’en-tête de l’entité-type ARTICLE : je subodore qu’ils devraient servir à compter les votes des utilisateurs, mais si tel était le cas, ils seraient alors redondants puisque faisant double emploi avec l’utilisation plus pertinente de la fonction COUNT appliquée aux tables SQL correspondantes : LIKE_M, SHARE_M et RATE_M.
    (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. Techno idéal pour site web (très) dynamique
    Par nicoxweb dans le forum Général Conception Web
    Réponses: 1
    Dernier message: 25/06/2006, 03h34
  2. [Architecture/strategie] conception de site web dynamique
    Par epoz dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 28/11/2005, 12h11
  3. IP Dynamique => pb hebergement de site web ?
    Par 17mounir dans le forum Développement
    Réponses: 2
    Dernier message: 29/07/2005, 22h51

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