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

Modélisation Discussion :

Validation diagramme bdd


Sujet :

Modélisation

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



    Allons-y pour la partie gauche...


    L’association entre LIGNE_FACTURE et AVOIR est à revoir, en effet elle se lit ainsi :

    — Une ligne de facture est au moins et au plus un avoir ;

    — Un avoir est parfois une ligne de facture.

    C’est une injection de LIGNE_FACTURE dans AVOIR.

    Par ailleurs la composition des clés primaires est inconsistante quant aux deux tables.




    Même remarque concernant les autres tables, selon votre diagramme :

    — Injection de FACTURE dans PAYPAL ;

    — Injection de FACTURE dans FACTURE_CHANGE ;

    — Injection de PROJET dans PROJET_CHANGE ;

    — Injection de FACTURE dans FACTURE_CHANGE ;

    — Bijection de FACTURE_CHANGE sur MONNAIE ;

    — Bijection de MONNAIE sur PROJET_CHANGE.

    Rien que ça !

    Il faudrait que vous expliquiez à quoi correspondent les tables PAYPAL, FACTURE_CHANGE, PROJET_CHANGE, MONNAIE, donc quelles sont les règles de gestion les gouvernant, sans oublier de corriger les cardinalités des liens, donc la constitution des clés.
    (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.

  2. #42
    Invité
    Invité(e)
    Par défaut
    Tu as plus rapide que moi pour répondre !!!

    Merci pour les explications sur les TRIGGERS & Co, j'avoue que cette partie est assez complexe pour moi, durant mes études, cela n'a même pas été abordé ...

    Pour commencer, voici le code SQL (fonctionnel) pour la partie de droite :

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
     
    CREATE SCHEMA IF NOT EXISTS `BDD` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
    USE `BDD` ;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`CLIENT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`CLIENT` (
      `id_client` INT NOT NULL AUTO_INCREMENT ,
      `raison_sociale` VARCHAR(50) NOT NULL ,
      `adresse` VARCHAR(50) NOT NULL ,
      `code_postal` VARCHAR(10) NOT NULL ,
      `ville` VARCHAR(50) NOT NULL ,
      `pays` VARCHAR(50) NOT NULL ,
      `numero_tva` VARCHAR(50) NOT NULL ,
      `delai_paiement_def` INT(2) NOT NULL ,
      `type_paiement_def` VARCHAR(20) NOT NULL ,
      `aff_total_mots_def` TINYINT(1) NOT NULL ,
      PRIMARY KEY (`id_client`) )
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`PROJET`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`PROJET` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `reference` VARCHAR(150) NOT NULL ,
      `description_projet` VARCHAR(255) NOT NULL ,
      `langue_source` VARCHAR(30) NOT NULL ,
      `date_projet_debut` DATE NOT NULL ,
      `date_projet_fin` DATE NOT NULL ,
      `nbjours` INT(5) NOT NULL ,
      `montant_total_projet` DECIMAL(10,2) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`) ,
      CONSTRAINT `fk_PROJET_1`
        FOREIGN KEY (`id_client` )
        REFERENCES `BDD`.`CLIENT` (`id_client` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`TACHE`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`TACHE` (
      `id_tache` INT NOT NULL AUTO_INCREMENT ,
      `tache` VARCHAR(100) NOT NULL ,
      `affichage_langue_facture` TINYINT(1) NOT NULL ,
      PRIMARY KEY (`id_tache`) )
    ENGINE = InnoDB;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`LIGNE_PROJET`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`LIGNE_PROJET` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `id_tache` INT NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_LIGNE_PROJET_1`
        FOREIGN KEY (`id_client` , `id_projet` )
        REFERENCES `BDD`.`PROJET` (`id_client` , `id_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT,
      CONSTRAINT `fk_LIGNE_PROJET_2`
        FOREIGN KEY (`id_tache` )
        REFERENCES `BDD`.`TACHE` (`id_tache` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`MOT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`MOT` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `NbMots` INT(10) NOT NULL ,
      `Tarif` INT(10) NOT NULL ,
      `MatchValeur` VARCHAR(45) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_MOT_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`FORFAIT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`FORFAIT` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `tarif_forfait` DECIMAL(10,4) NOT NULL ,
      INDEX `fk_FORFAIT_1` (`id_ligne_projet` ASC, `id_client` ASC, `id_projet` ASC) ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_FORFAIT_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`HEURE`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`HEURE` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `prix_heure` DECIMAL(10,4) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_HEURE_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    SET SQL_MODE=@OLD_SQL_MODE;
    SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
    SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

    Pour les TRIGGERS, j'ai donc tenté d'ajouter ceci au code :
    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
    CREATE TRIGGER MOT_EXCLUSION_TR BEFORE INSERT  ON MOT
    FOR EACH ROW 
    BEGIN
        SET @N = (
                  SELECT COUNT(*) 
                  FROM   FORFAIT 
                  WHERE  id_client = NEW.id_client
                    AND  id_projet = NEW.id_projet
                    AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps un forfait.' ;
        END IF ;	
         SET @N = (
                   SELECT COUNT(*) 
                   FROM   HEURE 
                   WHERE  id_client = NEW.id_client
                     AND  id_projet = NEW.id_projet
                     AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps une heure.' ;
        END IF ;
     
    END ;

    Résultat une belle erreur SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MySQL a répondu: Documentation
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 10
    Une erreur d'apostrophe ? Et pourtant, ce n'est pas à la ligne 10 ... Il s'agit de ");"

    CE TRIGGER passe sans souci :

    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
    COMMIT ;
    DELIMITER GO
     
    CREATE TRIGGER  LIGNE_PROJET_INCREMENT_TR BEFORE INSERT ON  LIGNE_PROJET 
    FOR EACH ROW
        BEGIN 
            SET NEW.id_ligne_projet = (SELECT COALESCE(MAX(id_ligne_projet) + 1, 1)  
                                     FROM   LIGNE_PROJET 
                                     WHERE  id_client = NEW.id_client AND id_projet = NEW.id_ligne_projet) ;
        END
     
    GO
    DELIMITER ;
    COMMIT ;

    Celui-ci aussi :

    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
    COMMIT ;
    DELIMITER GO
     
    CREATE TRIGGER  PROJET_INCREMENT_TR BEFORE INSERT ON  PROJET 
    FOR EACH ROW
        BEGIN 
            SET NEW.id_projet = (SELECT COALESCE(MAX(id_projet) + 1, 1)  
                                     FROM   PROJET 
                                     WHERE  id_client = NEW.id_client) ;
        END
     
    GO
    DELIMITER ;
    COMMIT ;

    Du coup, je me suis dis, pas besoin d'auto_increment pour la table HEURE, MOT et FORFAIT, de toute façon, sur quel champ je pourrais l'associer ? Puisqu'on recopie les valeurs de la table ligne_projet au niveau des clés primaires, non ? Dans votre script, on parle de MotID mais il n'existe pas ?

    Ce qui m'amène à votre dernier post :

    Alors effectivement, après relecture, il y a un souci avec la table AVOIR... Le but de cette table est comme son nom l'indique d'avoir un avoir sur une facture.
    Une facture peut obtenir un avoir mais ce n'est pas obligatoire.
    Du coup :
    FACTURE (0,1) ------ (1,1) AVOIR

    Pour PAYPAL, c'est très simple, si une facture est réglé par Paypal, une entrée se crée dans la table PAYPAL pour renseigner les frais + un lien vers un PDF de "preuve".

    Pour MONNAIE, FACTURE_CHANGE et PROJET_CHANGE, le tout est lié (comme tout la BDD vous allez me dire ).
    Les factures sont éditées en français mais au besoin, nous pouvons afficher en plus sur la facture le tarif dans une autre monnaie. D'où la table MONNAIE qui permet de lister les monnaie autres que l'EURO.

    Si on prend une facturation en Euro + DOLLAR :
    La table FACTURE_CHANGE permet d'avoir le total de la facture en dollar et surtout, d'avoir son taux de change à la date de l'édition.
    La table PROJET_CHANGE permet de ne pas seulement avoir le total en dollar mais aussi le détail en dollar de chaque projet.
    Comme je l'expliquais sur un autre post, il manque une partie car je ne sais pas qu'elle est la meilleure option pour modéliser cette partie, il faudrait pouvoir convertir la table MOT en dollars pour chaque Tarif/MatchValeur. Cette partie n'apparaît pas sur le diagramme car j'attendais de savoir si il y avait une meilleure option que de recréer une table MOT_CHANGE.
    La table HEURE et FORFAIT n'ont pas besoin d'une supplémentaire vu qu'elle ne possède qu'une ligne par projet au contraire de MOT.

    Merci !
    Orygynz

    [EDIT]
    Informations complémentaires, il peut être intéressant que tu compares la table PROJET_CHANGE avec le premier post de ce sujet, tu verras qu'à la base j'ajoutais directement les tarifs dans cette table. J'ai enlevé ça suite aux différentes modifications que l'on a effectué.
    Toutes les factures sont en euros et sur demande, on peut ajouter la partie "CHANGE", c'est à dire la partie détaillé et le montant total sous une autre monnaie.
    Donc pour les cardinalités :
    FACTURE (0,1) -----> (1,1) FACTURE_CHANGE
    PROJET (0,1) ---- > (1,1)PROJET_CHANGE ============> Qui sera sûrement modifié après nos échanges lol

    La table MONNAIE sert seulement à rentrer les monnaies en bdd.

    Merci !
    Orygynz
    Dernière modification par Invité ; 10/12/2014 à 21h26. Motif: Coloration syntaxique [code=SQL] ... [/code]

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



    Citation Envoyé par orygynz Voir le message
    Pour les TRIGGERS, j'ai donc tenté d'ajouter ceci au code [...]Résultat une belle erreur SQL
    A mon avis, soit MySQL vous en veut, soit on vous a jeté un sort... J’ai repris votre script (cf. ci-dessous), chez moi ça tourne comme une horloge (pour information, j’utilise la version 5.6).



    Citation Envoyé par orygynz Voir le message
    Du coup, je me suis dis, pas besoin d'auto_increment pour la table HEURE, MOT et FORFAIT, de toute façon, sur quel champ je pourrais l'associer ? Puisqu'on recopie les valeurs de la table ligne_projet au niveau des clés primaires, non ? Dans votre script, on parle de MotID mais il n'existe pas ?
    Pour HEURE et FORFAIT, il n’y a effectivement pas besoin d’auto-incrément supplémentaire, puisque pour une ligne de projet on a au plus un forfait ou une heure (cf. le diagramme du post #37). Par contre (cf. le même diagramme), les cardinalités disent bien que pour une ligne de projet on peut avoir plus d’un mot : il faut donc ajouter un attribut Id_Mot pour la table MOT, lequel fait partie de la clé primaire, sinon une ligne de projet serait limitée à un mot...



    Le script qui fonctionne chez moi (je n’ai pas recopié chaque attribut de chaque table) :

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    -- SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
     -- SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
     -- SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
     
    CREATE SCHEMA IF NOT EXISTS `BDD` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
    USE `BDD` ;
     
    drop TABLE if exists  PROJET ;
    drop TABLE if exists CLIENT ;
    drop TABLE if exists TACHE ;
    drop TABLE  if exists LIGNE_PROJET ;
    drop  TABLE if exists MOT ;
    drop TABLE if exists FORFAIT ;
    drop TABLE if exists HEURE ;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`CLIENT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`CLIENT` (
      `id_client` INT NOT NULL AUTO_INCREMENT ,
      `raison_sociale` VARCHAR(50) NOT NULL ,
      PRIMARY KEY (`id_client`) )
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`PROJET`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`PROJET` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `reference` VARCHAR(150) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`) ,
      CONSTRAINT `fk_PROJET_1`
        FOREIGN KEY (`id_client` )
        REFERENCES `BDD`.`CLIENT` (`id_client` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`TACHE`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`TACHE` (
      `id_tache` INT NOT NULL AUTO_INCREMENT ,
      `tache` VARCHAR(100) NOT NULL ,
      PRIMARY KEY (`id_tache`) )
    ENGINE = InnoDB;
     
     
    -- -----------------------------------------------------
    -- Table `BDD`.`LIGNE_PROJET`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`LIGNE_PROJET` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `id_tache` INT NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_LIGNE_PROJET_1`
        FOREIGN KEY (`id_client` , `id_projet` )
        REFERENCES `BDD`.`PROJET` (`id_client` , `id_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT,
      CONSTRAINT `fk_LIGNE_PROJET_2`
        FOREIGN KEY (`id_tache` )
        REFERENCES `BDD`.`TACHE` (`id_tache` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`MOT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`MOT` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
       id_mot int not null,
      `NbMots` INT(10) NOT NULL ,
      `Tarif` INT(10) NOT NULL ,
      `MatchValeur` VARCHAR(45) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`, id_mot) ,
      CONSTRAINT `fk_MOT_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`FORFAIT`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`FORFAIT` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `tarif_forfait` DECIMAL(10,4) NOT NULL ,
      -- -------------------------INDEX `fk_FORFAIT_1` (`id_ligne_projet` ASC, `id_client` ASC, `id_projet` ASC) ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_FORFAIT_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
    -- -----------------------------------------------------
    -- Table `BDD`.`HEURE`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `BDD`.`HEURE` (
      `id_client` INT NOT NULL ,
      `id_projet` INT NOT NULL ,
      `id_ligne_projet` INT NOT NULL ,
      `prix_heure` DECIMAL(10,4) NOT NULL ,
      PRIMARY KEY (`id_client`, `id_projet`, `id_ligne_projet`) ,
      CONSTRAINT `fk_HEURE_1`
        FOREIGN KEY (`id_client` , `id_projet` , `id_ligne_projet` )
        REFERENCES `BDD`.`LIGNE_PROJET` (`id_client` , `id_projet` , `id_ligne_projet` )
        ON DELETE RESTRICT
        ON UPDATE RESTRICT)
    ENGINE = InnoDB;
     
     COMMIT ;
     
     DELIMITER GO
     
    -- ----------------------------------------------------------------------------
    --  Le trigger pour incrémenter la colonne Id_Projet (table PROJET)
    -- ----------------------------------------------------------------------------
     
    CREATE TRIGGER  PROJET_INCREMENT_TR BEFORE INSERT ON PROJET 
    FOR EACH ROW
        BEGIN 
            SET NEW.Id_Projet = (SELECT COALESCE(MAX(Id_Projet) + 1, 1)  
                                     FROM   PROJET 
                                     WHERE  Id_Client = NEW.Id_Client) ;
        END
    GO
     
    -- ----------------------------------------------------------------------------
    --  Le trigger pour incrémenter la colonne Id_Ligne_Projet (table LIGNE_PROJET)
    -- ----------------------------------------------------------------------------
     
    CREATE TRIGGER  LIGNE_PROJET_INCREMENT_TR BEFORE INSERT ON  LIGNE_PROJET 
    FOR EACH ROW
        BEGIN 
            SET NEW.Id_Ligne_Projet = (SELECT COALESCE(MAX(Id_Ligne_Projet) + 1, 1)  
                                     FROM   LIGNE_PROJET 
                                     WHERE  Id_Client = NEW.Id_Client AND Id_Projet = NEW.Id_Projet) ;
        END
    GO
     
    -- ---------------------------------------------------------------
    -- Trigger pour la table MOT
    -- ---------------------------------------------------------------
    CREATE TRIGGER MOT_EXCLUSION_TR BEFORE INSERT  ON MOT
    FOR EACH ROW 
    BEGIN
        SET @N = (
                  SELECT COUNT(*) 
                  FROM   FORFAIT 
                  WHERE  id_client = NEW.id_client
                    AND  id_projet = NEW.id_projet
                    AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps un forfait.' ;
        END IF ;	
         SET @N = (
                   SELECT COUNT(*) 
                   FROM   HEURE 
                   WHERE  id_client = NEW.id_client
                     AND  id_projet = NEW.id_projet
                     AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps une heure.' ;
        END IF ;
     
       -- partie identification relative 
     
        SET NEW.Id_Mot = (SELECT COALESCE(MAX(Id_Mot) + 1, 1)  
                         FROM   MOT 
                         WHERE  id_client = NEW.id_client AND id_projet = NEW.id_projet AND id_ligne_projet = NEW.id_ligne_projet) ;
    END ;
     
    GO
     
     DELIMITER ;
     
    commit ;
     
    INSERT INTO CLIENT (Id_Client, Raison_Sociale) VALUES (1, 'Ets Naudin') ;
    INSERT INTO CLIENT (Id_Client, Raison_Sociale) VALUES (2, 'Volfoni SA') ;
    INSERT INTO CLIENT (Id_Client, Raison_Sociale) VALUES (3, 'Dubicobit') ;
     
    SELECT *, '' AS '<= CLIENT' FROM CLIENT ;
     
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (1, 0, 'Projet 1 de Naudin') ;
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (1, 0, 'Projet 2 de Naudin') ;
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (1, 0, 'Projet 3 de Naudin') ;
     
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (2, 0, 'Projet 1 de Volfoni') ;
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (2, 0, 'Projet 2 de Volfoni') ;
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (2, 0, 'Projet 3 de Volfoni') ;
     
    INSERT INTO PROJET (Id_Client, Id_Projet, Reference) VALUES (3, 0, 'Projet dingue de Dubicobit') ;
     
    SELECT *, '' AS '<= PROJET' FROM PROJET ;
    -- --------------------------------------------------------------------------------------
     
     
    INSERT INTO TACHE (Id_Tache, Tache) VALUES (1, 'tâche 01') ;
    INSERT INTO TACHE (Id_Tache, Tache) VALUES (2, 'tâche 02') ;
    INSERT INTO TACHE (Id_Tache, Tache) VALUES (3, 'tâche 03') ;
    INSERT INTO TACHE (Id_Tache, Tache) VALUES (4, 'tâche 04') ;
     
    SELECT *, '' AS '<= TACHE' FROM TACHE ;
     
    INSERT INTO  LIGNE_PROJET (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Tache) VALUES (1, 1, 0, 1) ;
     
    INSERT INTO  LIGNE_PROJET (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Tache) VALUES (1, 1, 0, 2) ;
    INSERT INTO  LIGNE_PROJET (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Tache) VALUES (2, 1, 0, 3) ;
    INSERT INTO  LIGNE_PROJET (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Tache) VALUES (2, 1, 0, 4) ;
     
    SELECT *, '' AS '<= LIGNE_PROJET' FROM LIGNE_PROJET ORDER BY 1, 2, 3;
     
    INSERT INTO FORFAIT (Id_Client, Id_Projet, Id_Ligne_Projet, tarif_forfait) VALUES (1, 1, 1, 10000) ;
     
    SELECT *, '' AS '<= FORFAIT' FROM FORFAIT ;
     
     
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (1, 1, 1, 0, 50, 100, 'collision avec FORFAIT !') ;
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (1, 1, 2, 0, 50, 100, 'Bonjour') ;
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (1, 1, 2, 0, 50, 200, 'Bonsoir') ;
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (2, 1, 1, 0, 10, 300, 'Sorry') ;
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (2, 1, 1, 0, 10, 400, 'Query') ;
    INSERT INTO  MOT (Id_Client, Id_Projet, Id_Ligne_Projet, Id_Mot, NbMots, Tarif, MatchValeur) VALUES (2, 1, 1, 0, 10, 500, 'Language') ;
     
    SELECT *, '' AS '<= MOT' FROM MOT ORDER BY 1, 2, 3, 4 ;
     
     
    -- SET SQL_MODE=@OLD_SQL_MODE;
    -- SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
    -- SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;


    Citation Envoyé par orygynz Voir le message
    Du coup : FACTURE (0,1) ------ (1,1) AVOIR
    Il faut donc renverser la vapeur dans le diagramme, ce qui donne :



    Et reprendre le triplet (id_client, id_facture, id_ligne_facture) pour la clé primaire de la table AVOIR. Si l’utilisateur a besoin de gérer un numéro d’avoir, il suffira d’ajouter un attribut à cet effet. Eviter NULL pour la colonne commentaires_avoir.


    Pour la table PAYPAL, même principe que pour la table AVOIR :




    Table PROJET_CHANGE

    Là encore, il faut permuter les cardinalités et retenir (id_client, id_projet) comme clé primaire. Par ailleurs, si la valeur de montant_total_projet_change est calculable en fonction de montant_total_projet et de taux_change_projet, inutile de conserver montant_total_projet_change « en dur ».


    Table MONNAIE :

    Transformer les bijections en injections.



    Citation Envoyé par orygynz Voir le message
    il faudrait pouvoir convertir la table MOT en dollars pour chaque Tarif/MatchValeur.
    Si la devise doit être la même pour l'ensemble des mots d’une ligne de projet, il faut et il suffit que cette devise soit connue au niveau de la ligne de projet. Si la devise doit être la même pour l'ensemble des lignes d'un projet, il faut et il suffit que cette devise soit connue au niveau du projet : pour cela la table PROJET_CHANGE devrait suffire pour s’en sortir.


    En attente d'un diagramme mis à jour...


    P.-S. Il reste un index dans le script...
    (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.

  4. #44
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Merci encore pour toutes ces infos. Pour MotID, il est clair que c'est mieux ainsi !

    Je vais modifier le diagramme ce soir, en attendant, je me posais 2 nouvelles questions

    Dans ce diagramme, nous sommes d'accord, la table LIGNE_PROJET pourrait avoir 2 id_ligne_projet pour 1 id_projet si seulement le projet comporte 2 tâches ? Si il n'y a qu'une tâche, on aura toujours 1 seul ligne par projet ?

    Pour ce TRIGGER :
    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
    -- ---------------------------------------------------------------
    -- Trigger pour la table MOT
    -- ---------------------------------------------------------------
    CREATE TRIGGER MOT_EXCLUSION_TR BEFORE INSERT  ON MOT
    FOR EACH ROW 
    BEGIN
        SET @N = (
                  SELECT COUNT(*) 
                  FROM   FORFAIT 
                  WHERE  id_client = NEW.id_client
                    AND  id_projet = NEW.id_projet
                    AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps un forfait.' ;
        END IF ;	
         SET @N = (
                   SELECT COUNT(*) 
                   FROM   HEURE 
                   WHERE  id_client = NEW.id_client
                     AND  id_projet = NEW.id_projet
                     AND  id_ligne_projet = NEW.id_ligne_projet
                 ) ;
        IF  @N > 0 THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'Un mot ne peut pas être en même temps une heure.' ;
        END IF ;

    Il faudra également que je fasse la même chose pour la table FORFAIT et HEURE ?

    Merci,
    Orygynz
    Dernière modification par Invité ; 10/12/2014 à 21h25. Motif: Coloration syntaxique [code=SQL] ... [/code]

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


    Citation Envoyé par orygynz Voir le message
    la table LIGNE_PROJET pourrait avoir 2 id_ligne_projet pour 1 id_projet si seulement le projet comporte 2 tâches ?
    Si l’on fait référence à votre dernier diagramme, une ligne de projet fait référence à une seule tâche, et une tâche peut être référencée par un nombre indéfini de lignes de projet. Pour sa part, un projet peut être en relation avec un nombre indéfini de tâches, puisqu’il n’y aucune contrainte modélisée entre PROJET et TACHE :


    Question : y a-t-il une contrainte impliquant PROJET et TACHE ?




    Citation Envoyé par orygynz Voir le message
    Il faudra également que je fasse la même chose pour la table FORFAIT et HEURE ?
    Au nom de la symétrie et de la réciprocité, la réponse est affirmative.
    (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.

  6. #46
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    J'ai retesté le TRIGGER toujours la même erreur, j'ai la version 5.5.40 de MySQL.

    J'ai tenté votre code (qui fonctionne ) et j'ai l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1644 - Un mot ne peut pas être en même temps un forfait.
    Pour moi entre PROJET et TACHE, il n'y a pas de contrainte, je réfléchissais et je me disais juste qu'en fait, on ne pourra jamais avoir ça :

    id_client id_projet id_ligne_projet id_tache
    1 1 1 1
    1 1 2 1

    Voici le nouveau diagramme qui je l'espère aura peu d'erreur :

    Nom : IMG-MCDv2-4.png
Affichages : 492
Taille : 182,3 Ko

    Et sinon, j'ai trouvé l'index dans la table FORFAIR Je le supprimerai lors de la prochaine saisie du code SQL.

    Merci !
    Orygynz

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



    J’avais écrit :
    Citation Envoyé par fsmrel Voir le message
    Table PROJET_CHANGE

    Là encore, il faut permuter les cardinalités et retenir (id_client, id_projet) comme clé primaire. Par ailleurs, si la valeur de montant_total_projet_change est calculable en fonction de montant_total_projet et de taux_change_projet, inutile de conserver montant_total_projet_change « en dur ».
    D’accord pour la clé primaire, vous avez rectifié , mais les cardinalités n’ont pas été permutées, autrement dit, selon votre dernier diagramme, un projet est toujours un projet change et un projet change est parfois un projet : situation dagobertienne... Plus généralement, vous êtes manifestement fâché avec les cardinalités, voici ce qu’on attend, le rouge remplaçant ce qui est en noir (en notant qu’une monnaie peut être utilisée pour plus d’une « facture change » et plus d’un « projet change ») :







    Citation Envoyé par orygynz Voir le message
    Pour moi entre PROJET et TACHE, il n'y a pas de contrainte, je réfléchissais et je me disais juste qu'en fait, on ne pourra jamais avoir ça :

    id_client id_projet id_ligne_projet id_tache
    1 1 1 1
    1 1 2 1
    Autrement dit, le triplet (id_client, id_projet, id_tache) est une clé alternative (cf. la contrainte LIGNE_PROJET_AK) :

    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 LIGNE_PROJET 
    (
              ClientId          INT             NOT NULL
            , ProjetId          INT             NOT NULL
            , LigneProjetId     INT             NOT NULL
            , TacheId           INT             NOT NULL
        , CONSTRAINT LIGNE_PROJET_PK PRIMARY KEY (ClientId, ProjetId, LigneProjetId)
        , CONSTRAINT LIGNE_PROJET_AK UNIQUE (ClientId, ProjetId, TacheId) 
        , CONSTRAINT LIGNE_PROJET_PROJET_FK FOREIGN KEY (ClientId, ProjetId)
              REFERENCES PROJET (ClientId, ProjetId) ON DELETE CASCADE
        , CONSTRAINT LIGNE_PROJET_TACHE_FK FOREIGN KEY (TacheId)
              REFERENCES TACHE (TacheId)
    ) ;

    Une question : une ligne de facture correspond-elle à une ligne de projet ?


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

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

  8. #48
    Invité
    Invité(e)
    Par défaut
    Cela ne fait aucun doute, on y arrivera !

    Ouais je devais pas être réveillé pour les cardinalités ... Avec une phrase c'est très simple, avec ces schémas, c'est autre chose ...

    La contrainte unique pour la table LIGNE_PROJET ne se fait pas automatiquement ? Une clé primaire est de toute façon unique et mySQL ne devrait pas pouvoir accepter 2 fois 1-1-1 pour le triplet ???

    Pour la question une ligne de facture correspond-elle à une ligne de projet ?
    Je vais répondre avec une explication sur la facturation pour éviter toute erreur sur la bdd.
    Pour éditer une facture, l'outil web va chercher si un client a 1 ou plusieurs projets dans le mois demandé. Si un client A a 3 projets, il va les chercher et sort un PDF tout beau tout chaud avec une entrée (une ligne) sur un tableau par projet et il fait le total en bas.
    Du coup, une facture peut avoir 1 projet à facturer comme 40... Tout ça est lié en fonction du client et de la date de fin du projet.
    Donc si je dis pas de connerie, oui une ligne facture correspond à un projet. Pour la ligne projet, je me pose la question pour une projet qui aurait 2 tâches différentes car c'est le seul cas où 1 projet pourrait avoir 2 ligne de projet

    Je remets un diagramme tout propre ce soir !

    Merci !
    Orygynz

  9. #49
    Invité
    Invité(e)
    Par défaut
    Et voici en exclusivité le dernier diagramme à jour !!!

    Nom : IMG-MCDv2-5.png
Affichages : 319
Taille : 183,3 Ko

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


    Y a encore du Dagobert... Dans les post #43, j’avais proposé ceci :




    Cas du devis :

    Comme dans le cas de la table FACTURE, à la racine de tout on doit trouver l’attribut id_client : la clé primaire de DEVIS est (id_client, id_devis). Quels sont les autres attributs de cette table ?



    Citation Envoyé par orygynz Voir le message
    La contrainte unique pour la table LIGNE_PROJET ne se fait pas automatiquement ? Une clé primaire est de toute façon unique et mySQL ne devrait pas pouvoir accepter 2 fois 1-1-1 pour le triplet ???
    On a défini le triplet (ClientId, ProjetId, LigneProjetId) comme étant clé (primaire) de la table LIGNE_PROJET, so far so good : le triplet (ClientId = 1, ProjetId = 1, LigneProjetId = 1) ne pourra donc pas exister plus d’une fois.

    Mais la paire (ClientId, ProjetId) pourra être présente N fois, puisqu’elle n’est pas clé. Etant donné qu’il n’y a initialement aucune hypothèse d’unicité quant à au triplet (ClientId, ProjetId, TacheId), lui aussi pourra exister N fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ClientId    ProjetId    LigneProjetId    TacheId
    --------    --------    -------------    -------
           1           1                1          1
           1           1                2          2
           1           1                3          1
         ...         ...              ...        ...
           1           1                n          1
    La seul façon d’assurer l’unicité du triplet (ClientId, ProjetId, TacheId) est bien de définir une clé supplémentaire (LIGNE_PROJET_AK) :

    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 LIGNE_PROJET 
    (
              ClientId          INT             NOT NULL
            , ProjetId          INT             NOT NULL
            , LigneProjetId     INT             NOT NULL
            , TacheId           INT             NOT NULL
        , CONSTRAINT LIGNE_PROJET_PK PRIMARY KEY (ClientId, ProjetId, LigneProjetId)
        , CONSTRAINT LIGNE_PROJET_AK UNIQUE (ClientId, ProjetId, TacheId) 
        , CONSTRAINT LIGNE_PROJET_PROJET_FK FOREIGN KEY (ClientId, ProjetId)
              REFERENCES PROJET (ClientId, ProjetId) ON DELETE CASCADE
        , CONSTRAINT LIGNE_PROJET_TACHE_FK FOREIGN KEY (TacheId)
              REFERENCES TACHE (TacheId)
    ) ;



    Citation Envoyé par orygynz Voir le message
    une ligne facture correspond à un projet
    Ce qui correspond à la modélisation présente dans votre diagramme :

    — Une ligne de facture fait référence à un et un seul projet ;

    — Un projet fait l’objet d’une ou plusieurs lignes de facture (et non pas : un projet fait l’objet d’une ligne de facture).

    On est bien d’accord ?
    (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.

  11. #51
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Merci pour vos réponses !

    Alors le cas du devis est assez bizarre, très peu utilisée mais si on prend l'idée du devis, on doit pouvoir éditer un devis pour un prospect/client avec des informations identiques à un projet avec une tâches, un type (forfait, mot...) et pouvoir le fournir dans une autre monnaie .... Et les informations de base utilisés dans une facture, un numéro, une date, etc...
    Dans ce cas et sur la base V1 actuelle, j'avais fais le choix de remettre dans une table quasiment l'ensemble des données mais dans ce cas, j'étais sur l'idée avec des champs cat1, cat 2, etc... Je sais que ce n'est pas la bonne méthode.
    Du coup pour ici, est-ce qu'il faut repartir sur une table LIGNE_DEVIS avec des tables FORFAIT, MOT, etc... dédié au devis vu qu'on ne saisie dans ces tables que des projets acceptés....

    Effectivement, dans mon schéma j'ai recopié bêtement la cardinalité vu que PAYPAL est en haut mais j'avais bien compris dans ce sens. (je suis pas fait pour les schémas )

    Avec vos explications, on est d'accord le contrainte UNIQUE est obligatoire, est-ce que l'on peut éditer cette contrainte dans MySQLworkbench ou c'est seulement sur le code ?
    Mais finalement, je vais changer le schéma, j'ai revu cette partie avec la traductrice et un projet aura toujours 1 seul tâche. Donc au final, un projet aura toujours une seule ligne.

    Ce qui correspond à la modélisation présente dans votre diagramme :

    — Une ligne de facture fait référence à un et un seul projet ;

    — Un projet fait l’objet d’une ou plusieurs lignes de facture (et non pas : un projet fait l’objet d’une ligne de facture).
    Alors oui, une ligne facture ne fait référence qu'à un seul projet...

    Pour l'autre je me pose la question... Si un projet a une seule ligne de projet, il aura forcément une seule ligne de facture... Et suite au changement vu dessus, je pense qu'on peut dire "un projet fait l'objet d'une ligne de facture".

    Ci-joint le nouveau schéma avec les changements :

    Nom : IMG-MCDv2-6.png
Affichages : 455
Taille : 182,6 Ko

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


    Citation Envoyé par orygynz Voir le message
    On est d'accord le contrainte UNIQUE est obligatoire, est-ce que l'on peut éditer cette contrainte dans MySQL workbench ou c'est seulement sur le code ?
    Je suppose qu’il ‘agit de la contrainte dans laquelle les tables LIGNE_PROJET et TACHE sont parties prenantes... Si c’est bien ça, alors je réponds : Les deux mon général ! Ce rustaud de MWB ne permet pas de déclarer des clés alternatives de plus d’une colonne, on doit donc descendre au rayon « quincaillerie », pour déclarer un index de type UNIQUE... :




    A la génération du code, on obtient :

    CREATE TABLE LIGNE_PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      LigneProjetId        INT           NOT NULL,
      TacheId              INT           NOT NULL,
      PRIMARY KEY (ClientId, ProjetId, LigneProjetId),
      INDEX LIGNE_PROJET_TACHE_FK1_idx (TacheId ASC),
      UNIQUE INDEX LIGNE_PROJET_TACHE_AK (ClientId ASC, ProjetId ASC, TacheId ASC),
      CONSTRAINT LIGNE_PROJET_PROJET_FK1
        FOREIGN KEY (ClientId, ProjetId) REFERENCES PROJET (ClientId, ProjetId)
        ON DELETE NO ACTION ON UPDATE NO ACTION,
      CONSTRAINT LIGNE_PROJET_TACHE_FK1
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
        ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ; 

    On commence par donner un nom de contrainte à la clé primaire de la table, par exemple « LIGNE_PROJET_PK » ;

    On supprime la ligne :

    INDEX LIGNE_PROJET_TACHE_FK1_idx (TacheId ASC)

    En effet, il est probable que cet index ne servira a priori à rien (quitte à le rajouter plus tard s’il s’avère qu’il est utile pour la performance des requêtes qui s’intéresseraient à une tâche en particulier).

    On remplace la ligne :

    UNIQUE INDEX LIGNE_PROJET_TACHE_AK (ClientId ASC, ProjetId ASC, TacheId ASC)

    Par celle-ci :

    CONSTRAINT LIGNE_PROJET_TACHE_AK UNIQUE (ClientId, ProjetId, TacheId)

    En effet, ne pas oublier qu’un index c’est de la quincaillerie, aussi le mot « index » ne figure pas dans la norme SQL. MySQL n’est pas regardant, mais il y a des limites...

    Au bout du compte :

    CREATE TABLE LIGNE_PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      LigneProjetId        INT           NOT NULL,
      TacheId              INT           NOT NULL,
      CONSTRAINT TABLE LIGNE_PROJET_PK PRIMARY KEY (ClientId, ProjetId, LigneProjetId),
      UNIQUE INDEX LIGNE_PROJET_TACHE_AK (ClientId ASC, ProjetId ASC, TacheId ASC),
      CONSTRAINT LIGNE_PROJET_PROJET_FK1
        FOREIGN KEY (ClientId, ProjetId) REFERENCES PROJET (ClientId, ProjetId)
        ON DELETE CASCADE,
      CONSTRAINT LIGNE_PROJET_TACHE_FK1
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
    ) ; 


    Citation Envoyé par orygynz Voir le message
    j'ai revu cette partie avec la traductrice et un projet aura toujours 1 seule tâche. Donc au final, un projet aura toujours une seule ligne.
    Comme dit Jean (dans Les tontons flingueurs, Quand ça change, ça change ! [/i] Il n’y a plus qu’à fondre PROJET et LIGNE_PROJET en une seule table...

    En passant, notez que vous avez encore fichu la patouille dans les cardinalités : si l’on en croit votre dernier diagramme, une tâche ne peut désormais faire référence qu’à une seule ligne de projet (ou à un seul projet dorénavant...)

    Dès que j’aurai un moment, je regarderai l’histoire des devis. La discussion avec Benallasiham vous donnera peut-être des idées.
    (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.

  13. #53
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Ok je propose ce soir un schéma avec PROJET / LIGNE_PROJET fusionné.

    J'ai été lire la discussion pour le devis et la difficulté, c'est vraiment le détail d'un projet MOT.
    Pour un Forfait ou une heure, on peut très bien stocker l'information directement dans la table DEVIS et ne faire qu'un lien avec CLIENT.

    Le lien entre DEVIS et FACTURE n'est pas nécessairement essentielle vu le peu de devis sur ce secteur. Dans ce cas, il faudrait peut-être ajouter une table MOT_DEVIS en lien avec le DEVIS. De mon côté, ça me semble être le plus simple mais ce n'est pas nécessairement le plus propre... Et cela oblige également à faire un lien avec la table MONNAIE et créer un DEVIS_CHANGE si besoin dans une autre devise.

    Merci beaucoup !
    Orygynz

  14. #54
    Invité
    Invité(e)
    Par défaut
    Je suis désolé pour le temps perdu... Je pensais pas que ça impactait autant d'avoir une seule tâche, je pensais qu'il fallait quand même une table LIGNE_PROJET pour avoir une base plus propre.... Et au final, si il n'y a plus de ligne_projet, les triggers vont plus être les mêmes... Enfin c'est le même principe derrière.

    Ci-joint, le nouveau diagramme :

    Nom : IMG-MCDv2-7.png
Affichages : 313
Taille : 173,7 Ko


    Merci!
    Orygynz

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


    Question déjà posée, mais, bis repetita placent :

    Un projet fait-il référence à une seule tâche ? Si oui, les cardinalités portées par le lien connectant les tables TACHE et PROJET sont pertinentes :

    [PROJET]>|-------------------------------------------------||-[TACHE]

    Mais alors l’attribut IdTache doit disparaître de la clé primaire de la table PROJET, sinon il y a contradiction.


    Si par ailleurs pour un client et une tâche il n’y a qu’un seul projet, on doit procéder comme on l’avait fait pour la table LIGNE_PROJET (cf. #52) :

    CREATE TABLE PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      TacheId              INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT PROJET_PK PRIMARY KEY (ClientId, ProjetId),
      CONSTRAINT UNIQUE PROJET_TACHE_AK (ClientId, TacheId),
      CONSTRAINT PROJET_CLIENT_FK
        FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
      CONSTRAINT PROJET_TACHE_FK
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
    ) ; 
    Quelle est votre position ?


    A propos du lien entre PROJET et LIGNE_FACTURE

    Revoilà les bijections ! Donc en principe les tables PROJET et LIGNE_FACTURE devraient être fondues en une seule... Mais si, lorsqu’on crée un projet, celui-ci n’est pas tout de suite facturé, on est donc plutôt en présence d’une injection :

    [LIGNE_ FACTURE]-|o----------------------------------------||--[PROJET]

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

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

  16. #56
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Alors oui, un projet ne fait référence qu'à une seule tâche mais une tâche peut faire référence à plusieurs projets. Du coup, je vais modifier la clé id_tache.

    Par contre, une contrainte unique id_client, id_tache, je comprends pas ...

    Exemple concret
    CLIENT : DURAND (id : 1)
    NOM DU PROJET : Conférence XXX-2014 (id : 1)
    TACHE : Traduction (id : 1)

    Du coup, le client Durant peut très bien faire appelle plusieurs fois (et c'est le cas ) à de la traduction. Par contre, ce sera un projet différent (souvent la référence de la source à traduire).
    Une tâche sera soit "Traduction", "Relecture" (relire une traduction effectué) ou "Transcription" (si mes souvenirs sont bons, traduction de l'oral en écrit)

    Donc au final, dans 95% des cas, les projets auront la tâche "Traduction". Mais je dois le savoir pour le préciser dans la facture, voilà pourquoi j'ai besoin de l'information par projet.
    Mais une table PROJETS ressemblera à ça :
    id_client id_projet id_tache
    1 1 1
    1 2 1
    1 3 2
    2 1 1


    Pour le lien entre LIEN_FACTURE et PROJET, je ne suis pas sûr de bien comprendre pour répondre ...
    Actuellement, sur ma 1ère base de données, j'ai la clé id_facture dans ma table PROJETS qui reste en NULL tant que cela n'est pas facturé. J'avais lu qu'il ne fallait surtout jamais faire comme ça en laissant des clés étrangères NULL. Du coup, je pensais avoir compris l'intérêt de votre table LIGNE_FACTURE.
    Je ne sais pas si cela répond à votre question...

    Merci !

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


    Citation Envoyé par orygynz Voir le message
    le client Durant peut très bien faire appelle plusieurs fois (et c'est le cas ) à de la traduction. Par contre, ce sera un projet différent.
    D’accord. On enlève donc la contrainte d’unicité :

    CREATE TABLE PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      TacheId              INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT PROJET_PK PRIMARY KEY (ClientId, ProjetId),
      CONSTRAINT UNIQUE PROJET_TACHE_AK (ClientId, TacheId),
      CONSTRAINT PROJET_CLIENT_FK
        FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
      CONSTRAINT PROJET_TACHE_FK
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
    ) ; 


    Citation Envoyé par orygynz Voir le message
    Pour le lien entre LIEN_FACTURE et PROJET, je ne suis pas sûr de bien comprendre pour répondre.
    Dans la mesure où l’on crée un projet avant sa facturation, et avec les règles suivantes :

    — Une ligne de facture fait référence à un et un seul projet ;

    — Un projet est référencé par au plus une ligne de facture.

    Alors la paire {Clientid, ProjetId} est clé candidate de la table LIGNE_ FACTURE. Le bout de diagramme suivant :


    [LIGNE_ FACTURE]-|o----------------------------------------||--[PROJET]


    Fait l’objet du code SQL :

    CREATE TABLE PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      TacheId              INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT PROJET_PK PRIMARY KEY (ClientId, ProjetId),
      CONSTRAINT PROJET_CLIENT_FK
        FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
      CONSTRAINT PROJET_TACHE_FK
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
    ) ; 
    CREATE TABLE LIGNE_FACTURE
    (
      ClientId             INT           NOT NULL,
      FactureId            INT           NOT NULL,
      LigneFactureId       INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT LIGNE_FACTURE_PK PRIMARY KEY (ClientId, FactureId, LigneFactureId),
      CONSTRAINT LIGNE_FACTURE_AK UNIQUE (ClientId, ProjetId),
      CONSTRAINT LIGNE_FACTURE_FACTURE_FK
        FOREIGN KEY (ClientId, FactureId) REFERENCES FACTURE (ClientId, FactureId)
           ON DELETE CASCADE,
      CONSTRAINT LIGNE_FACTURE_PROJET_FK
        FOREIGN KEY (ClientId, ProjetId) REFERENCES PROJET (ClientId, ProjetId)
    ) ; 
    Cela vous convient-il ? S'il y a des zones d'ombre, n'hésitez pas à le dire...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

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

  18. #58
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Ok pour la contrainte d'unicité, on est d'accord. En fait, j'y ai repensé après, la table TACHES est similaire à la table MONNAIE. Donc cette solution est la bonne.

    Pour la question de LIGNE_FACTURE, je comprends votre explication mais c'est juste la phrase de votre topic d'avant :

    Revoilà les bijections ! Donc en principe les tables PROJET et LIGNE_FACTURE devraient être fondues en une seule...
    Il est possible de fusionner ces tables ? On est bien obligé d'avoir une entrée NULL dans la table PROJET si on fait comme ça ?

    Je vous propose ce soir un diagramme édité avec les derniers ajustements.

    Merci beaucoup,
    Orygynz

  19. #59
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 965
    Points : 30 777
    Points
    30 777
    Billets dans le blog
    16
    Par défaut Injection ou bijection ?
    Bonsoir orygynz,


    Je rappelle d’abord que dans le cas de l’injection :

    [LIGNE_ FACTURE]-|o----------------------------------------||--[PROJET]

    Alors le code SQL à produire est le suivant :


    CREATE TABLE PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      TacheId              INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT PROJET_PK PRIMARY KEY (ClientId, ProjetId),
      CONSTRAINT PROJET_CLIENT_FK
        FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
      CONSTRAINT PROJET_TACHE_FK
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId)
    ) ; 
    CREATE TABLE LIGNE_FACTURE
    (
      ClientId             INT           NOT NULL,
      FactureId            INT           NOT NULL,
      LigneFactureId       INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT LIGNE_FACTURE_PK PRIMARY KEY (ClientId, FactureId, LigneFactureId),
      CONSTRAINT LIGNE_FACTURE_AK UNIQUE (ClientId, ProjetId),
      CONSTRAINT LIGNE_FACTURE_FACTURE_FK
        FOREIGN KEY (ClientId, FactureId) REFERENCES FACTURE (ClientId, FactureId)
           ON DELETE CASCADE,
      CONSTRAINT LIGNE_FACTURE_PROJET_FK
        FOREIGN KEY (ClientId, ProjetId) REFERENCES PROJET (ClientId, ProjetId)
    ) ; 

    En ce qui concerne la bijection :

    [LIGNE_ FACTURE]--||----------------------------------------||--[PROJET]


    Il est évident que vous n’êtes nullement obligé de fondre LIGNE_FACTURE et PROJET en une seule table. Mais se pose alors le problème suivant : la bijection ne peut pas être garantie par le jeu des clés étrangères. S’il y a bijection, LIGNE_FACTURE doit faire référence à PROJET et PROJET doit faire référence à LIGNE_FACTURE, sans possibilité que les colonnes soit « nullables », et l’on adaptera consciencieusement le code de création de la table PROJET :



    CREATE TABLE PROJET
    (
      ClientId             INT           NOT NULL,
      ProjetId             INT           NOT NULL,
      TacheId              INT           NOT NULL,
      FactureId            INT           NOT NULL,
      LigneFactureId       INT           NOT NULL,
      ...                  ...           ...
      CONSTRAINT PROJET_PK PRIMARY KEY (ClientId, ProjetId),
      CONSTRAINT PROJET_AK UNIQUE (ClientId, FactureId, LigneFactureId),
      CONSTRAINT PROJET_CLIENT_FK
        FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
      CONSTRAINT PROJET_TACHE_FK
        FOREIGN KEY (TacheId) REFERENCES TACHE (TacheId),
      CONSTRAINT PROJET_LIGNE_FACTURE_FK FOREIGN KEY (ClientId, FactureId, LigneFactureId)
          REFERENCES LIGNE_FACTURE (ClientId, FactureId, LigneFactureId) ; 
    Mais il y a comme un problème. En effet, rien n’empêchera que, dans la table LIGNE_FACTURE, la ligne de facture 123 fasse référence au projet 314,et que dans la table PROJET, ce projet 314 fasse référence à la ligne de facture 456 : d’un côté le projet 314 fait référence à la ligne de facture 123, tandis que de l’autre côté il fait référence à la ligne de facture 456...

    La bijection n’est pas donc pas respectée, alors que pour l’intégrité référentielle tout se passe bien (chaque valeur V de clé étrangère d’une table fait bien référence à V, valeur de clé primaire dans l’autre table) :


    
    LIGNE_FACTURE                                   PROJET
    +-------------------+-------------------+       +------------+-----------------+
    | LIGNE_FACTURE_PK  |  LIGNE_FACTURE_FK |       | PROJET_PK  |  PROJET_FK      |
    |                    | (projet)         |       |            | (ligne facture) |
    |-------------------+-------------------|       |------------+-------------- --|
    |              123  |               314 |       |       314  |        456      |
    |              456  |               271 |       |       271  |        123      |
    +-------------------+-------------------+       +------------+-----------------+
    
    

    Moralité, s’il y a bijection entre les deux tables, il faudra mettre en œuvre le code SQL (disons un trigger par table) garantissant la contrainte :

    LIGNE_FACTURE {ClientId, FactureId, LigneFactureId, ProjetId} = PROJET {ClientId, FactureId, LigneFactureId, ProjetId} ;


    Si quelque chose continue à vous tracasser, n’hésitez pas...
    (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.

  20. #60
    Invité
    Invité(e)
    Par défaut
    J'ai l'impression qu'on complique vachement le système non ?

    Dans ce cas, pourquoi ne pas faire une table LIGNE_FACTURE (id_client, id_projet, id_facture) avec les 3 champs en clé primaire.
    Pour l'avoir, on fait le lien direct avec la table FACTURE. Mauvaise idée ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2013] Débutant-Validation modélisation BDD inventaire d'optique
    Par Femtozaza dans le forum Modélisation
    Réponses: 55
    Dernier message: 07/05/2015, 17h50
  2. validation diagramme de classe d'une clinique
    Par elqorchi-najoua dans le forum Diagrammes de Classes
    Réponses: 3
    Dernier message: 12/10/2010, 12h36
  3. Validation diagrammes : use case
    Par nizar_grindi dans le forum Cas d'utilisation
    Réponses: 1
    Dernier message: 30/03/2010, 23h36
  4. Question et validation diagramme simple (débutant)
    Par dorian53 dans le forum Cas d'utilisation
    Réponses: 2
    Dernier message: 24/03/2010, 10h54
  5. validation diagramme de classe
    Par kokumbo dans le forum Diagrammes de Classes
    Réponses: 13
    Dernier message: 11/10/2009, 23h39

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