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 :

dupliquer des classes d'entité dans le MCD ?


Sujet :

Schéma

  1. #1
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut dupliquer des classes d'entité dans le MCD ?
    Bonjour,

    j'ai créé avec Looping un MCD pour mon projet. Auparavant, ne connaissant pas les MCD, j'avais directement créé une base de donnée sans faire de MCD. Il se trouve qu'à l'heure actuelle, le MCD ne décrit pas toutes les situations. En effet, les cas d'erreur ne sont pas pris en compte.
    Mon MCD actuel est le suivant :
    Nom : MCD3x1000.png
Affichages : 182
Taille : 96,0 Ko

    Dans ce MCD, il y a les 2 classes d'entitée license et ticket qui vont conduire à la création de 2 tables SQL license et ticket. Or, dans l'ancienne bdd, il y avait aussi les classes SQL license_error et ticket_error, dont l'utilité était qu'en cas d'erreur détectée (une donnée reçue est erronée), au lieu de faire une écriture dans la table tableXX, on fait une écriture dans la table tableXX_error. Ainsi, le code est conservé mais on ne pollue pas les tables license et ticket en cas d'erreur. Afin de modifier le moins possible le code existant, je souhaite conserver ce mécanisme, même s'il n'est pas optimal.
    Il y a donc lieu d'enrichir le MCD avec 2 nouvelles classes d'entités license_error et ticket_error. La question que je me pose concerne les associations et les cardinalités : va-t-il falloir créer les associations concern_l_error, own_error, concern_t_error et create_ticket_error avec les mêmes cardinalités que dans le cas sans erreur ? J'attends une réponse avant de me lancer dans la mise à jour (assez lourde) du modèle.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 287
    Points : 23 309
    Points
    23 309
    Billets dans le blog
    2
    Par défaut
    bonjour LaurentSc

    Comme toujours, la modélisation conceptuelle dépendra des règles de gestion.

    Si par exemple si on peut détecter zéro à plusieurs erreurs pour une licence, il faudra modéliser :
    LICENCE 0,n --- detecter --- 1,1(R) ERREUR

  3. #3
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Bonjour escartefigue,

    n'ayant aucune expérience sur les MCDs, j'ai du mal à comprendre votre réponse.

    Voici comment je la comprends et mes interrogations.

    D'abord, vous voyez en plus de la classe LICENCE, une classe ERREUR.

    Les règles de gestion associées seraient :

    - une licence peut détecter 0 à n erreurs.

    - une erreur est détectée par une et une seule licence ; le formalisme (R) signifie identifiant relatif et donc qu'il y a une clé étrangère sur une licence.

    Donc si la licence a détecté une erreur (pas obligé), cette erreur est reliée à la licence avec une cardinalité (1,1).

    Si j'ai bien compris votre réponse, ça signifie que vous éliminez la création des classes license_erroret ticket_error. On est d'accord ? Ca signifie que mon code actuel devra être profondément remanié, ce qui ne me réjouit pas...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 287
    Points : 23 309
    Points
    23 309
    Billets dans le blog
    2
    Par défaut
    Ce que je propose c'est le modèle suivant (MCD et MLD dérivé)

    Nom : Sans titre.png
Affichages : 224
Taille : 10,0 Ko

    La table LICENSE_ERROR est bien créée, son identifiant est composé de l'identifiant de la licence (identification relative notée (R) oblige) + l'identifiant de l'erreur.

    Voici le script produit par Looping en sélectionnant SQL server (je ne sais pas quel est votre SGBD, à adapter si besoin) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TABLE LI_license(
       LI_ident INT IDENTITY,
       LI_activate_date DATE,
       LI_deactivate_date DATE NOT NULL,
       PRIMARY KEY(LI_ident)
    );
     
    CREATE TABLE LE_license_error(
       LI_ident INT,
       LE_ident INT IDENTITY,
       PRIMARY KEY(LI_ident, LE_ident),
       FOREIGN KEY(LI_ident) REFERENCES LI_license(LI_ident)
    );

    Même raisonnement pour TICKET et TICKET_ERROR bien sûr

  5. #5
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Votre proposition se rapproche de mon besoin ; néanmoins, l'idéal serait que la structure de la classe LE_license_error soit quasiment identique à celle de la classe LI_license (mêmes rubriques à part l'identifiant et en commun la clé étrangère vers la classe application). On peut faire ça ? Si oui, le code PHP suivant reste utilisable :
    Code php : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    $table = ($error) ? "licenseError" :  "license";
     
      if ($deactivatedate)
                {
                    $sql_insert = "
    INSERT into `" .
                        $table .
                        "`  (sesa, application_key, activate_date, deactivate_date)
     SELECT
    {$ppi($sesaid,'int')}, application_key, 
    {$ppi( $activatedate ) }, {$ppi( $deactivatedate ) } from 
    `application` 
    WHERE application_name={$ppi($applicationname)}
    ";
                }
                else
                {
                    $sql_insert = "
    INSERT into `" .
                        $table .
                        "`  (sesa, application_key, activate_date)
     SELECT
    {$ppi($sesaid, 'int')}, application_key, 
    {$ppi( $activatedate  ) } from `application` WHERE application_name={$ppi($applicationname)}
    ";
                }
                $id = $ppi->insert($sql_insert);
    sesa est l'identifiant des classes licenseet license_error.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 287
    Points : 23 309
    Points
    23 309
    Billets dans le blog
    2
    Par défaut
    C'est possible, mais est-ce vraiment nécessaire ?
    En quoi, les valeurs des attributs communs entre "license" et "license_error" divergent-ils ? Stocker deux fois les mêmes informations est inutile et dangereux.
    Il faudrait donner quelques exemples de contenu (1 ou 2 licences avec le contenu exhaustif de leurs erreurs respectives)

  7. #7
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    septembre 2006
    Messages
    7 577
    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 : 7 577
    Points : 28 926
    Points
    28 926
    Billets dans le blog
    16
    Par défaut
    Bonjour,


    Citation Envoyé par laurentSc Voir le message
    une licence peut détecter 0 à n erreurs.
    En l’occurrence le verbe détecter n’est pas pertinent, une détection n’est pas faite par un objet passif tel qu’une licence, mais par un acteur humain ou un process. Une licence peut être affectée de 0 à N erreurs, comporter de 0 à N erreurs, être l’objet de 0 à N erreurs, etc.


    Citation Envoyé par laurentSc Voir le message
    Si j'ai bien compris votre réponse, ça signifie que vous éliminez la création des classes license_error et ticket_error.
    Au contraire, réfléchissez bien, la proposition d’Escartefigue conduit à la création de ces classes !


    Citation Envoyé par laurentSc Voir le message
    Si oui, le code PHP suivant reste utilisable
    Je ne sais pas si Escartefigue connaît PHP, en tout cas moi pas. Merci de fournir la structure (donc la liste des attributs et leur rôle) que vous attendez pour chacune des classes (et tables SQL).
     
    (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à pout ça.

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 287
    Points : 23 309
    Points
    23 309
    Billets dans le blog
    2
    Par défaut
    Je ne connais pas non plus PHP.

    Une explication sur le rôle des attributs liés aux erreurs et des exemples de contenu sont indispensables à ma compréhension du besoin.
    Encore une fois, sauf cas très particulier, la redondance d'attributs et de contenu est à proscrire

  9. #9
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Au contraire, réfléchissez bien, la proposition d’Escartefigue conduit à la création de ces classes !
    Certes, mais c'était pas encore le cas à 10h06...

    Citation Envoyé par fsmrel Voir le message
    Merci de fournir la structure (donc la liste des attributs et leur rôle) que vous attendez pour chacune des classes (et tables SQL).
     
    Citation Envoyé par escartefigue Voir le message
    C'est possible, mais est-ce vraiment nécessaire ?
    En quoi, les valeurs des attributs communs entre "license" et "license_error" divergent-ils ? Stocker deux fois les mêmes informations est inutile et dangereux.
    Il faudrait donner quelques exemples de contenu (1 ou 2 licences avec le contenu exhaustif de leurs erreurs respectives)
    Il n'est pas question de stocker 2 fois les mêmes informations, mais selon la présence ou non d'une erreur, aiguiller soit vers la table license, soit vers la table license_error.
    Le fichier CSV d'où viennent les données comporte 23 colonnes. Je ne vais donner dans mon exemple que les colonnes utiles.
    1-SESAID => 10008
    2-APPLICATIONNAME => TeamForge_Full
    3-PLATFORM => Software Engineering
    4-PLATFORMOWNER => SESA69723
    5-ACTIVATEDATE => 09/11/2013
    6-DEACTIVATEDATE => 25/03/2014é  (erreur volontairement introduite pour tester)
    
    La 1e colonne est un identifiant ; les colonnes 2 à 4 vont servir à alimenter la table application et les colonnes 5 et 6 la table license ou la table license_error.
    Voici la structure des 2 tables SQL que j'avais créées avant de connaître le MCD :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE `license` (
      `id_license` int NOT NULL,
      `id_application_appl` smallint NOT NULL,
      `activate_date` date DEFAULT NULL,
      `deactivate_date` date DEFAULT NULL,
      PRIMARY KEY (`sesa`,`id_application_appl`) USING BTREE,
      KEY `FK_APPLICATION` (`id_application_appl`),
      CONSTRAINT `FK_APPLICATION` FOREIGN KEY (`id_application_appl`) REFERENCES `application` (`id_application`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE `license_error` (
      `sesa` int NOT NULL,
      `id_application_appl` smallint NOT NULL,
      `activate_date` date DEFAULT NULL,
      `deactivate_date` date DEFAULT NULL,
      PRIMARY KEY (`sesa`,`id_application_appl`) USING BTREE,
      KEY `FK_APPLICATION2` (`id_application_appl`),
      CONSTRAINT `FK_APPLICATION2` FOREIGN KEY (`id_application_appl`) REFERENCES `application` (`id_application`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

    et de la table application:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE `application` (
      `id_application` smallint NOT NULL AUTO_INCREMENT,
      `appli_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
      `platform` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
      `platform_owner` bigint DEFAULT NULL,
      `publisher` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
      PRIMARY KEY (`id_application`),
      UNIQUE KEY `UK_appli_name` (`appli_name`) 
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

    Voici un exemple d'INSERT dans la table license :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT into `license`  (id_license, id_application_appl, activate_date, deactivate_date)
     SELECT
    10008, id_application, 
    '2013-11-09', '2014-03-25' 
    from `application` 
    WHERE appli_name='TeamForge_Full'
    j'ai retiré l'erreur sur la colonne deactivate_date
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  10. #10
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 287
    Points : 23 309
    Points
    23 309
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    Certes, mais c'était pas encore le cas à 10h06...
    C'était bien le cas, mais j'avais rédigé un MCD sous forme littérale et non pas sous forme graphique, peut-être moins facile à lire du coup

    Pour le reste, le DDL de la table license_error ne convient pas : il manque l'identifiant de la licence (FK) permettant de vérifier la règle de gestion selon laquelle
    une licence est concernée par zéro à plusieurs erreurs.
    D'après le DDL, on trouve dans "license_error"
    - l'identifiant application : inutile puisque une licence concerne une et une seule application
    - l'identifiant SESA qu'on ne trouve pas dans "license"
    - activate_date et deactivate_date, a priori redondantes avec la table "license"

  11. #11
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    je ne sais pas quel est votre SGBD, à adapter si besoin
    MySQL.

    Citation Envoyé par escartefigue Voir le message
    C'était bien le cas, mais j'avais rédigé un MCD sous forme littérale et non pas sous forme graphique, peut-être moins facile à lire du coup
    C'est surtout qu'il y avait la table ERREUR et que je n'avais pas compris que c'était pour license_error...

    Citation Envoyé par escartefigue Voir le message
    Pour le reste, le DDL de la table license_error ne convient pas : il manque l'identifiant de la licence (FK) permettant de vérifier la règle de gestion selon laquelle
    une licence est concernée par zéro à plusieurs erreurs.
    je n'avais prévu de lien (donc de FK) entre les tables license et license_error. Certes, on pourrait prévoir un tel identifiant mais si une erreur est détectée, on ne s'adresse jamais à la table license, donc pas sûr qu'il soit utile.


    Citation Envoyé par escartefigue Voir le message
    D'après le DDL, on trouve dans "license_error"

    - l'identifiant SESA qu'on ne trouve pas dans "license"
    Je me suis trompé dans le DDL de license_error, le nom des colonnes ayant changé :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE `licenseerror` (
      `id_license` int NOT NULL,
      `id_application_appl` smallint NOT NULL,
      `activate_date` date DEFAULT NULL,
      `deactivate_date` date DEFAULT NULL,
      PRIMARY KEY (`id_license`,`id_application_appl`) USING BTREE,
      KEY `FK_APPLICATION2` (`id_application_appl`),
      CONSTRAINT `FK_APPLICATION2` FOREIGN KEY (`id_application_appl`) REFERENCES `application` (`id_application`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;



    Citation Envoyé par escartefigue Voir le message
    - l'identifiant application : inutile puisque une licence concerne une et une seule application
    La FK vers la table application me paraît nécessaire justement pour spécifier quelle application est concernée par la licence...


    Citation Envoyé par escartefigue Voir le message
    - activate_date et deactivate_date, a priori redondantes avec la table "license"
    C'est volontaire car les requêtes "INSERT" ou "UPDATE" sont systématiquement effectuées mais selon la détection ou non d'une erreur, on le fait sur la table license ou license_error et donc le code SQL ne change pas excepté le nom de la table (qui est passé en paramètre).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

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


    Selon votre MCD (association CONCERNE_L), une licence fait référence à au moins et au plus une application. Au stade MLD, cela se traduit par une dépendance fonctionnelle dans la table LICENCE :

    {id_licence} → {id_application}. Cette DF vaut dans tous les cas de figure, autrement dit elle s’applique de facto pour la table license_error.


    Examinons votre code SQL :

    CREATE TABLE licenseerror (
      id_license int NOT NULL,
      id_application_appl smallint NOT NULL,
      activate_date date DEFAULT NULL,
      deactivate_date date DEFAULT NULL,
      PRIMARY KEY (id_license,id_application_appl) USING BTREE,
      KEY FK_APPLICATION2 (id_application_appl),
      CONSTRAINT FK_APPLICATION2 FOREIGN KEY (id_application_appl) 
          REFERENCES application (id_application) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 
    Du fait de la dépendance fonctionnelle, il y a viol de la 2NF (deuxième forme normale), ce qui est passible des tribunaux relationnels. Votre MCD doit être conforme à ce qu’a modélisé Escartefigue dans le post #4. En conséquence, dans votre CREATE TABLE il faut remplacer l’attribut id_application_appl par l’auto-incrément LE_ident (à renommer à votre guise). Exemple :

    CREATE TABLE license_error (
      id_license int NOT NULL,
      le_ident smallint NOT NULL auto_increment,
      activate_date date DEFAULT NULL,
      deactivate_date date DEFAULT NULL,
      PRIMARY KEY (id_license, le_ident)
    ) ; 
    Voire :

    CREATE TABLE license_error (
      id_license int NOT NULL,
      le_ident smallint NOT NULL auto_increment,
      activate_date date,
      deactivate_date date,
      constraint license_error_pk PRIMARY KEY (id_license, le_ident),
      constraint license_error_ak unique (le_ident)
      ) ; 
    Car MySQL (au moins avec la version 5.7) exige inutilement qu’un auto-incrément fasse l’objet d’une clé à lui tout seul.

    Pour retrouver l’application associée à une erreur, on effectue une jointure entre les tables application, license et license_error. Exemple :

    select appli_name 
    from   license_error as x
      join license as y on x.id_license = y.id_license
      join application as z on y.id_application_appl = z.id_application
    where le_ident = 1 
    ;
    Structure correspondante des tables concernées :

     CREATE TABLE application
    (
     id_application smallint NOT NULL AUTO_INCREMENT,
      appli_name varchar(30) NOT NULL,
      platform varchar(30) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
      PRIMARY KEY (id_application),
      UNIQUE KEY appli_UK_appli_name (appli_name) 
    ) ; 
    
    CREATE TABLE license 
    (
            id_license int NOT NULL auto_increment,
            id_application_appl smallint NOT NULL,
            activate_date date,
            deactivate_date date,
          PRIMARY KEY (id_license) 
        , CONSTRAINT FK_APPLICATION FOREIGN KEY (id_application_appl) 
              REFERENCES application (id_application)
    ) ; 
    
    CREATE TABLE license_error (
      id_license int NOT NULL,
      le_ident smallint NOT NULL auto_increment,
      activate_date date,
      deactivate_date date,
      constraint license_error_pk PRIMARY KEY (id_license, le_ident),
      constraint license_error_ak unique (le_ident)
      , constraint license_error_fk foreign key (id_license) 
            references license (id_license)
    ) ; 
    Un bout de jeu d’essai :

    insert into application (appli_name, platform)
    values ('appli 1', 'platforme 7')
         , ('appli 2', 'platforme 7')
    ;
    insert into license (id_application_appl, activate_date, deactivate_date)
    values ((select id_application from application where appli_name = 'appli 1'), '2021-12-12' , '2021-12-14')
    ;
    insert into license_error (id_license, activate_date, deactivate_date)
    values (1, '2021-12-15' , '2021-12-17') 
         , (1, '2021-12-19' , '2021-12-20')
    ;
    
    Soit dit en passant, pour faciliter les SELECT, on peut créer une vue :

    create view license_error_v 
    as 
    select appli_name, y.id_license, le_ident
    from   license_error as x
      join license as y on x.id_license = y.id_license
      join application as z on y.id_application_appl = z.id_application
    ;
    D’où la requête permettant de retrouver facilement l’application référencée par une erreur de licence (en l’occurrence le_ident = 1) :

    select * from license_error_v where le_ident = 1 ; 
    En notant que MySQL est à la traîne et ne permet pas qu’un trigger porte sur une vue . A défaut, pour effectuer des inserts et des updates sur une vue, changer de SGBD.
    (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à pout ça.

  13. #13
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Merci pour votre longue réponse. Ce soir, impossible de suivre. Demain matin, je serai plus frais, mais je crains que ça reste trop difficile pour moi.

    Notamment, la dépendance fonctionnel, pas vu dans le bouquin de Paprick (j'en suis à peu près aux 2/3) ; j'espère demain assimiler ce concept...

    Citation Envoyé par fsmrel Voir le message
    ce qui est passible des tribunaux relationnels.
    Heureusement que la peine de mort est abolie
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  14. #14
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    septembre 2006
    Messages
    7 577
    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 : 7 577
    Points : 28 926
    Points
    28 926
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    Notamment, la dépendance fonctionnel, pas vu dans le bouquin de Paprick (j'en suis à peu près aux 2/3) ; j'espère demain assimiler ce concept...
    La dépendance fonctionnelle n’est pas dans le champ de Merise. Pour en parler sciemment, il faut commencer par les axiomes et règles d’Armstrong, mais il s’agit alors d’une étude à accompagner d’un doliprane (ou d’une bouteille de scotch, au choix)…
    (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à pout ça.

  15. #15
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Comme prévu, ce matin, je comprends mieux...Je me pose des questions.

    Citation Envoyé par fsmrel Voir le message
    {id_licence} → {id_application}. Cette DF vaut dans tous les cas de figure, autrement dit elle s’applique de facto pour la table license_error.
    Si ça vaut aussi pour la table license_error, je suppose que c'est car elle comporte aussi une colonne id_licence. OK ?



    Citation Envoyé par fsmrel Voir le message
    Pour retrouver l’application associée à une erreur, on effectue une jointure entre les tables application, license et license_error. Exemple :

    select appli_name 
    from   license_error as x
      join license as y on x.id_license = y.id_license
      join application as z on y.id_application_appl = z.id_application
    where le_ident =application  1 
    ;
    Au sujet de cette requête, ça serait pas plutôt select z.appli_name etc sachant qu'il n'y a que la table applicationqui possède une colonne appli_name ?

    Citation Envoyé par fsmrel Voir le message
    mais il s’agit alors d’une étude à accompagner d’un doliprane (ou d’une bouteille de scotch, au choix)…
    N'aimant pas le whisky, ça sera plutôt un doliprane...Et y a pas que pour cette étude car pour moi, ça vaut pour tous les liens sur votre article https://fsmrel.developpez.com/basesr...normalisation/...

    Citation Envoyé par fsmrel Voir le message
    En notant que MySQL est à la traîne et ne permet pas qu’un trigger porte sur une vue . A défaut, pour effectuer des inserts et des updates sur une vue, changer de SGBD.
    Changer de SGBD serait une tâche colossale. Comme j'approche de la fin de mon projet, je ne compte pas tenter le coup...

    Concernant la table license_error, celle-ci n'a pas de FK vers la table application. Or quand je reçois des données erronées, au lieu d'écrire dans la table license, j'écris dans la table license_error. Ci-après un exemple de requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    INSERT into `license_error` (id_license, id_application_appl, activate_date, deactivate_date)
     SELECT
    12345, id_application, 
    2021-05-21, 2021-05-22 from 
    `application` 
    WHERE appli_name='TeamForge_Full'
    Il faudrait pas ajouter une colonne id_application_appl et mettre une FK ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  16. #16
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    septembre 2006
    Messages
    7 577
    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 : 7 577
    Points : 28 926
    Points
    28 926
    Billets dans le blog
    16
    Par défaut
    Bonjour,  


    Citation Envoyé par laurentSc Voir le message
    Si ça vaut aussi pour la table license_error, je suppose que c'est car elle comporte aussi une colonne id_licence
    Bien entendu.

    Il va sans dire que le CREATE TABLE que j’ai proposé dans mon précédent message pour cette table est inférable du MCD proposé par Escartefigue (cf. post #4) :

    Nom : Sans titre.png
Affichages : 224
Taille : 10,0 Ko

    Je rappelle ce que j’ai codé :

    CREATE TABLE license_error (
      id_license int NOT NULL,
      le_ident smallint NOT NULL auto_increment,
      activate_date date,
      deactivate_date date,
      constraint license_error_pk PRIMARY KEY (id_license, le_ident),
      constraint license_error_ak unique (le_ident)
      , constraint license_error_fk foreign key (id_license) 
            references license (id_license)
    ) ; 

    Citation Envoyé par laurentSc Voir le message
    Au sujet de cette requête, ça serait pas plutôt select z.appli_name etc sachant qu'il n'y a que la table application qui possède une colonne appli_name ?
    L’alias z est ici facultatif car il n’y a pas d’équivoque. Par contre, si l’on faisait mention de la colonne id_license dans l’instruction SELECT, alors il faudrait écrire x.id_license ou y.id_license pour que l’ambiguïté détectée par le SGBD disparaisse.


    Citation Envoyé par laurentSc Voir le message
    quand je reçois des données erronées, au lieu d'écrire dans la table license, j'écris dans la table license_error.
    De deux choses l’une :

    Soit le MCD proposé par Escartefigue est celui que est à retenir, soit il faut rompre le lien entre LICENSE et LICENSE_ERROR. A vous lire, on a l’impression que le MCD serait celui-ci, où l’on fait le distinguo entre les licences validées et celles qui ne le sont pas :

    Nom : laurentSc(license_error)a.png
Affichages : 132
Taille : 12,2 Ko
    Figure (a)


    MCD qui pourrait du reste être ramené à celui-ci-dessous, dans lequel un booléen permet de savoir quelle est le statut de la licence (valide ou non) :
    Nom : laurentSc(license_error)b.png
Affichages : 132
Taille : 12,1 Ko
    Figure (b)
    (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à pout ça.

  17. #17
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    septembre 2006
    Messages
    7 577
    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 : 7 577
    Points : 28 926
    Points
    28 926
    Billets dans le blog
    16
    Par défaut
    Une variante pour la modélisation des licences.
    Si les licences validées et celles qui ne le sont pas n’ont pas les mêmes attributs, on peut envisager une spécialisation (héritage) :

    Nom : laurentSc(license_err)specialisation.png
Affichages : 130
Taille : 16,2 Ko
    Figure (c)

    Les attributs validateDate et deactivateDate sont censés être pertinents quel que soit le type de licence (validée ou erronée). Si tel n’est pas le cas, les sortir de LICENCE et les expédier dans la sous-classe adéquate.

    En passant, quelle est votre version de mySQL ?
    (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à pout ça.

  18. #18
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Tout d'abord, merci pour vos posts #16 et #17.

    Je n'ai pas répondu tout de suite car je ne voulais pas interrompre un travail déjà démarré.

    Comme je l'ai déjà dit, je souhaite générer un modèle qui permettra de modifier le moins possible le code existant :
    post #1 :
    Ainsi, le code est conservé mais on ne pollue pas les tables license et ticket en cas d'erreur. Afin de modifier le moins possible le code existant, je souhaite conserver ce mécanisme, même s'il n'est pas optimal.
    post #5 :
    l'idéal serait que la structure de la classe LE_license_error soit quasiment identique à celle de la classe LI_license (mêmes rubriques à part l'identifiant et en commun la clé étrangère vers la classe application).
    Je me suis donc inspirer de vos réponses pour générer un modèle respectant cette contrainte :

    Nom : MCD3x1500.png
Affichages : 123
Taille : 184,8 Ko
    Il se rapproche de la figure (a) du post #16, donc pas de lien entre les tables licenseet license_error. Elle me permet plus que le modèle de la figure (b) de modifier le moins possible le code existant (qui suppose l'existence de 2 tables)

    Même si je ne connais pas encore la notion d'héritage des classes d'entités, quand j'aurai appris cette notion, je reviendrai sur votre figure (c) du post #17. Par contre, il faudra déporter les attributs activeDate et deactiveDate, car il faut aucune écriture en cas d'erreur.

    Mon modèle conduit aux requêtes SQL suivantes :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    CREATE TABLE user_table(
       id_user INT AUTO_INCREMENT,
       sesa INT NOT NULL,
       firstname VARCHAR(255),
       lastname VARCHAR(255),
       email VARCHAR(255),
       company VARCHAR(50),
       buunitname VARCHAR(50),
       id_user_manager INT,
       id_location INT NOT NULL,
       PRIMARY KEY(id_user),
       UNIQUE(sesa),
       FOREIGN KEY(id_user_manager) REFERENCES user_table(id_user),
       FOREIGN KEY(id_location) REFERENCES location(id_location)
    );
     
    CREATE TABLE application(
       id_application INT AUTO_INCREMENT,
       appli_name VARCHAR(50) NOT NULL,
       platform_owner VARCHAR(50),
       platform VARCHAR(50),
       publisher VARCHAR(50),
       id_user INT NOT NULL,
       PRIMARY KEY(id_application),
       UNIQUE(appli_name),
       FOREIGN KEY(id_user) REFERENCES user_table(id_user)
    );
     
    CREATE TABLE license(
       id_license INT AUTO_INCREMENT,
       activate_date DATE,
       deactivate_date DATE,
       id_application_appl INT NOT NULL,
       PRIMARY KEY(id_license),
       FOREIGN KEY(id_application_appl) REFERENCES application(id_application)
    );
     
    CREATE TABLE ticket(
       id_ticket INT AUTO_INCREMENT,
       num_ticket BIGINT NOT NULL,
       assigned_group VARCHAR(30),
       submitted_date DATE,
       last_resolved_date DATE,
       summary VARCHAR(200),
       priority VARCHAR(6),
       status VARCHAR(13),
       type_incident VARCHAR(10),
       source VARCHAR(12),
       first_country VARCHAR(30),
       id_user INT NOT NULL,
       id_application INT NOT NULL,
       PRIMARY KEY(id_ticket),
       UNIQUE(num_ticket),
       FOREIGN KEY(id_user) REFERENCES user_table(id_user),
       FOREIGN KEY(id_application) REFERENCES application(id_application)
    );
     
    CREATE TABLE license_error(
       id_license INT AUTO_INCREMENT,
       activate_date DATE,
       deactivate_date DATE,
       id_application_appl INT NOT NULL,
       PRIMARY KEY(id_license),
       FOREIGN KEY(id_application_appl) REFERENCES application(id_application)
    );
     
    CREATE TABLE ticket_error(
       id_ticket INT AUTO_INCREMENT,
       num_ticket BIGINT,
       assigned_group VARCHAR(30),
       submitted_date DATE,
       last_resolved_date DATE,
       summary VARCHAR(200),
       priority VARCHAR(6),
       status VARCHAR(13),
       type_incident VARCHAR(10),
       source VARCHAR(12),
       first_country VARCHAR(30),
       id_application INT NOT NULL,
       id_user INT NOT NULL,
       PRIMARY KEY(id_ticket),
       UNIQUE(num_ticket),
       FOREIGN KEY(id_application) REFERENCES application(id_application),
       FOREIGN KEY(id_user) REFERENCES user_table(id_user)
    );

    Citation Envoyé par fsmrel Voir le message
    En passant, quelle est votre version de mySQL ?
    8.0.20
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

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


    La figure (a) est celle qui vous convient : pas de problème. Dans le cadre de votre étude de la modélisation, vous noterez en passant qu’avec la spécialisation/généralisation, non seulement on peut factoriser des attributs communs aux sous-classes, mais on peut aussi factoriser les associations (OWN dans l’exemple ci-dessous) :

    Nom : laurentSc(license_err)specialisation(2e).png
Affichages : 121
Taille : 24,5 Ko
    Figure (d)
     
     
    (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à pout ça.

  20. #20
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 588
    Points : 4 113
    Points
    4 113
    Billets dans le blog
    1
    Par défaut
    Merci pour votre message.
    Je vois comme intérêt la réduction du nombre d'associations vers la classe application. Dans votre exemple il y a bien OWNmais aussi LIC_APP, n'est-ce pas ?

    Dans mon modèle, j'ai dupliqué ces 2 associations. Pour les licences, pour OWN, il y avait own et own_error, et pour LIC_APP, concern_l et concern_le(et idem pour les tickets). Par contre, je ne pense pas factoriser des attributs car dans le cas d'erreur (ici license_error), il ne faut rien écrire.

    En fait, j'ai mis à jour la bdd hier, et j'ai passé toute la journée à modifier le code PHP qui gère la bdd (et c'est loin d'être fini...).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

Discussions similaires

  1. Utilisation des classes managées .net dans PHP
    Par Hinault Romaric dans le forum Langage
    Réponses: 2
    Dernier message: 19/02/2011, 10h46
  2. Réponses: 1
    Dernier message: 08/10/2009, 16h38
  3. besoin d'aide pour intégrer une entité dans un MCD
    Par barkleyfr dans le forum Schéma
    Réponses: 17
    Dernier message: 13/10/2005, 13h29

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