Bonsoir sohiermdp,
Concernant votre MCD :
Historisez-vous les adresses de livraison ? La cardinalité 1,N portée par la patte connectant ADRESSE et HISTORISER indiquerait une réponse positive.
La clé de la table FACTURE est réductible, car en l’état pour une facture d’un client, on pourrait avoir plusieurs adresses et plusieurs dates d’historisation.
Une facture fait nécessairement référence à une adresse historisée. Qu’en est-il lorsque l’adresse de facturation est en cours ?
Quoi qu'il en soit, je propose le scénario alternatif suivant :
Pour la partie des adresses qui sont en cours (non historisées) :
A noter que les factures sont en relation directe avec les clients et font (facultativement) référence à une adresse de facturation en cours. La cardinalité 0,1 signifie qu’une facture ne fait pas nécessairement référence à une adresse de facturation en cours, en effet, quand l’adresse de factorisation a été historisée, les factures sont alors branchées sur leur adresse de facturation qui a été transférée dans la partie historisation.
N.B. Avec Open ModelSphere, quand les cardinalités sont soulignées, cela signifie qu’on utilise l’identification relative. Par ailleurs, le triangle connectant ADRESSE_EN_COURS et ADRESSE_FACTURATION symbolise la spécialisation (une adresse de facturation est une adresse).
Passage au niveau logique, sous forme d’un diagramme tabulaire (MySQL Workbench) :
Remarques :
Les attributs participant à la fois à la clé primaire et à une clé étrangère sont accompagnés d’une clé rouge (), tandis que les attributs participant seulement à la clé primaire sont accompagnés d’une clé jaune ().
L’attribut AdresseId ne fait pas partie de la clé primaire de la table ADRESSE_FACTURATION. En effet, un client n’a qu’une seule adresse de facturation en cours.
Afin d’éviter la présence du bonhomme Null (horresco referens !) au sein de la clé étrangère qui aurait branché FACTURE sur ADRESSE_FACTURATION, l’association Adresser a fait l’objet d’une table, nommée ici FACTURE_ADRESSE_EN_COURS.
La table FACTURE_ADRESSE_EN_COURS ne contient qu’une seule fois l’attribut ClientId : cela garantit la contrainte de chemin qui veut que les factures d’un client fassent référence à l’adresse de facturation de ce client et pas à celle d’un autre client (c’est pour pouvoir garantir cette contrainte qu’on a utilisé l’identification relative pour les adresses et les factures).
Les cardinalités donnent lieu à la lecture suivante :
Un client a de 0 à N adresses en cours (lien CLIENT - ADRESSE_EN_COURS) ;
Une adresse en cours appartient à un et un seul client (lien CLIENT - ADRESSE_EN_COURS) ;
Une adresse en cours peut être une adresse de facturation (lien ADRESSE_EN_COURS – ADRESSE_FACTURATION) ;
Une adresse de facturation est une adresse (lien ADRESSE_FACTURATION - ADRESSE_EN_COURS) ;
Un client a de 0 à N factures (lien CLIENT - FACTURE) ;
Une facture appartient à un et un seul client (lien CLIENT - FACTURE) ;
Une adresse de facturation en cours est utilisée pour 0 à N factures (lien ADRESSE_FACTURATION – FACTURE_ADRESSE_en_COURS) ;
Une facture peut avoir pour adresse au plus une adresse de facturation en cours (lien FACTURE - FACTURE_ADRESSE_en_COURS).
Prise en compte de l’historisation des adresses
La partie historisation des adresses est le miroir de la partie adresses en cours (à supposer qu’on historise les adresses quel que soit leur type, livraison ou facturation) :
Diagramme tabulaire :
Les cardinalités donnent lieu à la lecture suivante :
Un client a de 0 à N adresses historisées (lien CLIENT - ADRESSE_HISTO) ;
Une adresse historisée appartient à un et un seul client (lien CLIENT - ADRESSE_HISTO) ;
Une adresse historisée peut être une adresse de facturation (lien ADRESSE_HISTO – ADRESSE_HISTO_FACT) ;
Une adresse de facturation historisée est une adresse historisée (lien ADRESSE_HISTO – ADRESSE_HISTO_FACT) ;
Une adresse de facturation historisée a été utilisée pour 0 à N factures (lien ADRESSE_HISTO_FACT – FACT_ADRESE_HISTO_FACT) ;
Une facture peut avoir pour adresse au plus une adresse de facturation historisée (lien FACTURE - FACT_ADRESE_HISTO_FACT).
Quand on historise une adresse :
(a) On insère une ligne pour cette adresse dans la table ADRESSE_HISTO (l’attribut AdresseHistoId est incrémenté d’une unité relativement à l’attribut ClientId) ;
(b) S’il s’agit d’une adresse de facturation, on insère une ligne dans la table ADRESSE_HISTO_FACT, avec une valeur de clé primaire égale à la valeur de la clé primaire de la ligne qui vient d’être créée dans la table parente ADRESSE_HISTO ;
(c) Via la table FACT_ADRESSE_HISTO_FACT, on branche sur ADRESSE_HISTO_FACT les factures concernées, à savoir celles dont la valeur du singleton {ClientId} dans FACTURE_ADRESSE_EN_COURS est égale à la valeur de la clé primaire {ClientId} des lignes qui, du fait de l’historisation, seront supprimées de la table ADRESSE_FACTURATION (c'est-à-dire celles dont la valeur de la paire {ClientId, AdresseId} est égale à la valeur de la clé primaire {ClientId, AdresseId} de l’adresse supprimée (table ADRESSE_EN_COURS)).
(d) Une fois le branchement effectué, on supprime dans FACTURE_ADRESSE_EN_COURS les lignes correspondant aux factures qui viennent de faire l’objet d’un ajout dans la table FACT_ADRESSE_HISTO_FACT.
(e) On supprime l’adresse en cours (table ADRESSE_EN_COURS, et ADRESSE_FACTURATION par effet CASCADE).
N.B. Une facture a au moins et au plus une adresse de facturation. Il s'agit :
Soit de l'adresse de facturation en cours ;
Soit d'une adresse de facturation historisée.
Avec un SGBD SQL, cette contrainte sera sous-traitée au SGBD, au moyen d’une assertion (ou d’un trigger si le SGBD ne propose pas l’instruction CREATE ASSERTION).
Tout ceci n’est évidemment qu’une proposition pour un scénario alternatif...
Partager