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 :

Gestion de commandes


Sujet :

Schéma

  1. #1
    Membre actif Avatar de arthuro45
    Profil pro
    Développeur du dimanche
    Inscrit en
    Juillet 2009
    Messages
    602
    Détails du profil
    Informations personnelles :
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Juillet 2009
    Messages : 602
    Points : 265
    Points
    265
    Par défaut Gestion de commandes
    Bonjour,

    Je tente de modéliser un MCD concernant une gestion de commande qui débouchera sur des livraisons. Je n'ai pas l'habitude d'écrire des règles de gestion, j'aimerais votre avis, voyez-vous des erreurs, des incohérences ?

    Le principe de base :

    Les client passent des commandes dans un outil extérieur au mien.
    J'importe ces commandes dans une table temporaire (TEMP_COMMANDE_OUTIL_EXT) avant de les intégrer dans la table commande.
    Une commande a son propre statut et elle est composée de ligne de commande.
    Chaque ligne de commande a son propre statut.
    Les commandes sont traités par un ou plusieurs utilisateurs, et elles changent de statut au fur et à mesure de leur traitement (préparation etc..).
    Les fournisseurs livrent des articles qui seront ajoutés au stock.

    Voici les règles de gestion :

    Une commande possède un seul client.
    Un client peut posséder plusieurs commandes.

    Une commande est composée d'au moins une ligne de commande.
    Une ligne de commande ne dépend que d'une seule commande.

    Une commande ne peut se voir attribuer qu'un seul statut_commande à la fois.
    Un statut_commande peut être attribué à plusieurs commandes.

    Une ligne de commande ne peut se voir attribuer qu'un seul statut_ligne à la fois.
    Un statut_ligne peut être attribué à plusieurs lignes de commande.

    Une ligne de commande ne concerne qu'un seul article.
    Un article ne concerne qu'une seule ligne de commande.

    Un article est associé à une seule catégorie.
    Une catégorie peut-être associer à plusieurs articles.

    Un fournisseur peut ajouter plusieurs articles.
    Un article peut être ajouté par un seul fournisseur.

    Un utilisateur peut traiter plusieurs commandes;
    Une commande peut être traité par plusieurs utilisateurs.

    Une commande est archivée une seule fois.

    Pour le moment les tables sont incomplètes concernant leurs champs.

    Le graphique :

    Nom : mcd.png
Affichages : 8806
Taille : 26,4 Ko

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

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

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


    Votre effort d’énoncer les règles de gestion est méritoire et à signaler, car bien souvent les forumeurs n’ont pas le courage d'en faire autant.


    Quelques petits conseils :

    Pensez à numéroter ces règles, par exemple :

    RG01 - Une commande possède un seul client.

    RG02 - Un client peut posséder plusieurs commandes.

    Etc.

    Même si ça n’est pas toujours facile, essayez d’utiliser le verbe qui soit le plus pertinent pour établir le lien entre les objets. Par exemple :

    RG01 - Une commande est passée par un seul client.

    RG02 - Un client peut passer plusieurs commandes.

    Mais il ne faut pas non plus s’acharner : si en manque d’inspiration vous modélisiez ainsi, à moins d’être plus royaliste que le roi, on ne saurait vous en tenir rigueur :
    [CLIENT]----1,N----(COM_CLI)----1,1----[COMMANDE]
    Quitte à passer pour un scripteur au style lourd, utilisez de préférence les termes « exactement » ou « un et un seul » pour exprimer les cardinalités 1-1, l’essentiel est de ne pas être ambigu :

    Une commande est passée par exactement un client.
    Ou
    Une commande est passée par un et un seul client.

    En procédant ainsi, on met plus facilement en évidence les éventuelles contradictions entre les énoncés des règles et leur traduction sous forme de cardinalités.

    Ainsi, quand vous écrivez :
    Un client peut passer plusieurs commandes.
    Cela veut dire qu’un client peut ne pas avoir encore passé de commande, mais on se prend à douter, car la cardinalité correspondante dans votre MCD est 1,N signifiant qu’un client a passé au moins une commande...

    Question 1

    Qu’entendez-vous par « Une commande est archivée une seule fois » ? Je suppose qu’au stade de la base de données rendue opérationnelle, une opération d’archivage consiste d’abord à recopier la commande C dans [la table] HISTORIQUE puis à la supprimer de [la table] COMMANDE, mais s'il en est ainsi, qu’advient-il des lignes de commande ?

    Question 2

    Pourquoi la patte connectant l’entité-type COMMANDE et l’association Attribuer1 est-elle porteuse d’une cardinalité 0,1 ? Une commande a toujours un statut. Sinon c’est refiler la patate chaude aux requêtes SQL, qui devront interpréter cela comme « statut inconnu » et l’on s’embarque pour les terrae incognitae de la logique trivalente (voire quadrivalente si en plus de la non valeur « inconnu » il faut aussi traiter de la non valeur « sans objet »), terrain glissant s’il en est. Je ne dis pas que 0,1 est interdit dans le cas général, mais alors au niveau tabulaire on doit procéder comme si on avait modélisé ainsi au stade MCD :

    STATUT]----0,N----( )----1,1----[COMMANDE_A_STATUT]----1,1----( )----0,1----[COMMANDE]
    Où, pour paraphraser Open ModelSphere, 1,1 signifie que COMMANDE_A_STATUT a pour identifiant celui de COMMANDE, il en hérite (possibilité non prévue par AnalyseSI, trop fruste).

    Ce qui vaut pour COMMANDE vaut bien sûr pour LIGNE_COMMANDE.

    Question 3

    Pourquoi la patte connectant l’entité-type ARTICLE et l’association CONCERNE est-elle porteuse d’une cardinalité 1,1 ? Si vous vendez la Tour Eiffel ou Le Louvre, d’accord, sinon s’il s’agit de l’article « Arthur, sa vie son œuvre » ayant fait l’objet d’un million de lignes de commande, alors vous aurez un million de fois cet article dans [la table] ARTICLE, bijection oblige. En l’occurrence un article est une instance (Quantite = 1) alors qu’en général la cardinalité en cause est 0,N ce qui signifie donc qu’on ne s’intéresse pas à une instance en particulier mais à un nombre N d’instances connu grâce à l'attribut Quantite.


    Question 4

    Pourquoi la patte connectant COMMANDE et TEMP_COMMANDE_OUTIL_EXT (à vos souhaits !) est-elle porteuse d’une cardinalité 1,N ? Vous n’en dites pas assez...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

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

  3. #3
    Membre actif Avatar de arthuro45
    Profil pro
    Développeur du dimanche
    Inscrit en
    Juillet 2009
    Messages
    602
    Détails du profil
    Informations personnelles :
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Juillet 2009
    Messages : 602
    Points : 265
    Points
    265
    Par défaut
    Bonjour ,

    Merci pour votre réponse très complète.

    Suivant vos conseils, j'ai modifié la syntaxe de mes règles de gestion RG01 etc... ainsi que les termes utilisés pour clarifier une règle "un et un seul ..


    Ainsi, quand vous écrivez :
    Un client peut passer plusieurs commandes.
    Cela veut dire qu’un client peut ne pas avoir encore passé de commande, mais on se prend à douter, car la cardinalité correspondante dans votre MCD est 1,N signifiant qu’un client a passé au moins une commande...
    Effectivement avec cette règle : Un client peut passer plusieurs commandes, j'ai modifié la cardinalité en conséquence :
    [CLIENT]----0,N----(COM_CLI)----1,1----[COMMANDE]


    Question 1

    Qu’entendez-vous par « Une commande est archivée une seule fois » ? Je suppose qu’au stade de la base de données rendue opérationnelle, une opération d’archivage consiste d’abord à recopier la commande C dans [la table] HISTORIQUE puis à la supprimer de [la table] COMMANDE, mais s'il en est ainsi, qu’advient-il des lignes de commande ?
    Mon opération d'archivage est identique à votre description.
    qu’advient-il des lignes de commande ?
    La question est pertinente effectivement, je pensais ajouter les lignes de commande à la table Historique ? Cela évite de créer deux tables, HistoriqueCde et HistoriqueLigneCde.
    cde1 ligne1
    cde1 ligne2
    cde1 ligne3
    cde2 ligne1
    etc...


    Question 2

    Pourquoi la patte connectant l’entité-type COMMANDE et l’association Attribuer1 est-elle porteuse d’une cardinalité 0,1 ? Une commande a toujours un statut. Sinon c’est refiler la patate chaude aux requêtes SQL, qui devront interpréter cela comme « statut inconnu » et l’on s’embarque pour les terrae incognitae de la logique trivalente (voire quadrivalente si en plus de la non valeur « inconnu » il faut aussi traiter de la non valeur « sans objet »), terrain glissant s’il en est. Je ne dis pas que 0,1 est interdit dans le cas général, mais alors au niveau tabulaire on doit procéder comme si on avait modélisé ainsi au stade MCD :
    STATUT]----0,N----( )----1,1----[COMMANDE_A_STATUT]----1,1----( )----0,1----[COMMANDE]
    Où, pour paraphraser Open ModelSphere, 1,1 signifie que COMMANDE_A_STATUT a pour identifiant celui de COMMANDE, il en hérite (possibilité non prévue par AnalyseSI, trop fruste).

    Ce qui vaut pour COMMANDE vaut bien sûr pour LIGNE_COMMANDE.
    C'est effectivement une erreur de ma part, une commande aura toujours un et un seul statut (à la fois), j'ai donc modifié la relation :
    [COMMANDE]----1,N----(Attribuer 1)----1,1----[STATUT_COMMANDE]


    Question 3

    Pourquoi la patte connectant l’entité-type ARTICLE et l’association CONCERNE est-elle porteuse d’une cardinalité 1,1 ? Si vous vendez la Tour Eiffel ou Le Louvre, d’accord, sinon s’il s’agit de l’article « Arthur, sa vie son œuvre » ayant fait l’objet d’un million de lignes de commande, alors vous aurez un million de fois cet article dans [la table] ARTICLE, bijection oblige. En l’occurrence un article est une instance (Quantite = 1) alors qu’en général la cardinalité en cause est 0,N ce qui signifie donc qu’on ne s’intéresse pas à une instance en particulier mais à un nombre N d’instances connu grâce à l'attribut Quantite.
    Effectivement ce n'était pas logique, j'ai modifié les règles en conséquence :
    RG09 - Une ligne de commande ne concerne qu'un et un seul article.
    RG10 - Un article peut concerner plusieurs lignes de commande.


    Question 4

    Pourquoi la patte connectant COMMANDE et TEMP_COMMANDE_OUTIL_EXT (à vos souhaits !) est-elle porteuse d’une cardinalité 1,N ? Vous n’en dites pas assez...
    1,N signifie que je peux importer une ou plusieurs commandes.


    Voici les règles de gestion modifiées :

    RG01 - Une commande est passée par un et un seul client.
    RG02 - Un client peut passer plusieurs commandes.

    RG03 - Une commande est composée d'au moins une ligne de commande.
    RG04 - Une ligne de commande ne dépend que d'une et une seule commande.

    RG05 - Une commande ne peut se voir attribuer qu'un et un seul statut_commande à la fois.
    RG06 - Un statut_commande peut être attribué à plusieurs commandes.

    RG07 - Une ligne de commande ne peut se voir attribuer qu'un et un seul statut_ligne à la fois.
    RG08 - Un statut_ligne peut être attribué à plusieurs lignes de commande.

    RG09 - Une ligne de commande ne concerne qu'un et un seul article.
    RG10 - Un article peut concerner plusieurs lignes de commande.

    RG11 - Un article est associé à une et une seule catégorie.
    RG12 - Une catégorie peut-être associée à plusieurs articles.

    RG13 - Un fournisseur peut ajouter plusieurs articles.
    RG14 - Un article peut être ajouté par un et un seul fournisseur.

    RG15 - Un utilisateur peut gérer plusieurs commandes.
    RG16 - Une commande peut être gérée par plusieurs utilisateurs.

    RG17 - Une commande est archivée une et une seule fois.
    RG18 – Une ligne de commande est archivée une et une seule fois.

    Le MCD modifié :
    Nom : mcd.png
Affichages : 4757
Taille : 26,4 Ko

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

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

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


    On avance, toutefois :

    Il y a des cardinalités à permuter dans le diagramme (associations Attribuer1 et Attribuer2).

    Le diagramme comporte encore une cardinalité 0,1 sur la patte connectant LIGNE_COMMANDE et COMPOSEE_DE.


    Cas de l’archivage

    Dans votre diagramme, la patte connectant COMMANDE et ARCHIVER est porteuse d’une cardinalité 1,1, ce qui veut dire qu’une commande participe une et une seule fois à l’association ARCHIVER, autrement dit, en traversant le miroir de l’association, on se rend compte qu'une commande ne fait référence qu’à un seul « historique » et à une seule ligne de commande (laquelle peut être un élément d’une autre commande par le canal de l’association COMPOSEE_DE). Comme dit l'autre, y a de l'embrouille, voire du mou dans la corde à nœuds...

    Par ailleurs vous écrivez :

    Citation Envoyé par arthuro45 Voir le message
    je pensais ajouter les lignes de commande à la table Historique ? Cela évite de créer deux tables, HistoriqueCde et HistoriqueLigneCde.
    Il est impératif de voir les conséquences de la mise en œuvre d’une seule table HISTORIQUE. Au stade SQL, elle aura (au minimum) la structure suivante (les éléments de la clé primaire sont soulignés) :
    IdCommande, DateArchivage, NumeroCommande, DateCommande, DateReception, DateEmission, IdClient, IdStatutCde, IdLigneCde, Quantite, IdArticle, IdStatutLigne 
    Balek ! Pour chaque ligne de commande il faudra fournir tous les éléments de la commande correspondante : date de commande, client, etc. Il y aura de la redondance à profusion... En l’occurrence on violera la 2NF (deuxième forme normale) ce qui est peccamineux : pour être pardonné on devra normaliser en 2NF, c'est-à-dire décomposer la table HISTORIQUE en deux tables, une pour les commandes et une autre pour les lignes. Ainsi on repassera par la case Départ...

    Par ailleurs, une fois qu’on aura historisé un commande, et puisqu’on l’aura éliminée physiquement de la table COMMANDE (même principe pour les lignes), on devra conserver les liens avec les autres tables : CLIENT, ARTICLE, STATUT_COMMANDE, STATUT_LIGNE, sinon comment savoir par exemple que la commande 1234 fait référence au client Raoul ? (d’autant plus que rien ne s’oppose à la suppression de Raoul si aucune autre commande n’y fait référence...)

    Autrement dit, pour modéliser correctement l’historisation on est obligé d’avoir un système de commandes en double, ce qui est lourd et pas très simple à manipuler...

    Une solution bien moins lourde à laquelle vous pouvez réfléchir : mettre en œuvre une table COMMANDE_ARCHIVEE appendice de la table COMMANDE, ce qui permettrait savoir si une commande est active ou archivée (supprimée non pas physiquement mais logiquement) :


    MCD



    Le soulignement de la cardinalité 1,1 signifie (dans le style Open ModelSphere) que l’identifiant de COMMANDE_ARCHIVEE est hérité de celui de COMMANDE : il y a identification de COMMANDE_ARCHIVEE relativement à COMMANDE (ce qu’AnalyseSI ne sait pas faire).


    MLD correspondant



    Ainsi, les commandes actives et celles qui sont archivées seront regroupées dans la table COMMANDE, mais vous pourrez définir des tables virtuelles (vues) permettant par exemple de voir les commandes actives comme isolées des commandes archivées.


    Au stade SQL (façon MS SQL Server) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE TABLE COMMANDE
    (
       IdCommande           Int                  Not null,
       NumeroCommande       Varchar(12)          Not null,
       DateCommande         Datetime             Not null,
       Etc                  Varchar(64)          Not null,
       CONSTRAINT COMMANDE_PK PRIMARY KEY (IdCommande),
       CONSTRAINT COMMANDE_AK UNIQUE (NumeroCommande)
    ) ;
    CREATE TABLE COMMANDE_ARCHIVEE
    (
       IdCommande           Int                  Not null,
       DateArchivage        Datetime             Not null,
       CONSTRAINT COMMANDE_ARCHIVEE_PK PRIMARY KEY (IdCommande),
       CONSTRAINT COMMANDE_ARCHIVEE_COMMANDE_FK FOREIGN KEY (IdCommande) REFERENCES COMMANDE
    ) ;

    Pour ne voir que les commandes actives sous forme tabulaire :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE VIEW COMMANDE_ACTIVE (IdCommande, NumeroCommande, DateCommande, Etc) 
      AS
        SELECT IdCommande, NumeroCommande, DateCommande, Etc
        FROM   COMMANDE AS x
        WHERE  NOT EXISTS 
              (
               SELECT ''
               FROM   COMMANDE_ARCHIVEE AS y
               WHERE  x.IdCommande = y.IdCommande
              ) ;

    Pour tout savoir sur les commandes archivées :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE VIEW COMMANDE_ARCHIVEE_V (IdCommande, NumeroCommande, DateCommande, DateArchivage, Etc) 
      AS
        SELECT x.IdCommande, NumeroCommande, DateCommande, DateArchivage, Etc
        FROM   COMMANDE AS x JOIN COMMANDE_ARCHIVEE AS y ON x.IdCommande = y.IdCommande ;

    Un début de jeu d’essai :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO COMMANDE (IdCommande, NumeroCommande, DateCommande, Etc) VALUES (1, '1234', '2013-04-01', 'Un') ;
    INSERT INTO COMMANDE (IdCommande, NumeroCommande, DateCommande, Etc) VALUES (2, '2345', '2013-07-14', 'Deux') ;

    Archivage de la 2e commande :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO COMMANDE_ARCHIVEE (IdCommande, DateArchivage) VALUES (2, '2013-08-27') ;

    Commandes actives et archivées confondues :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '' AS 'COMMANDE', * FROM COMMANDE ;
    =>
    IdCommande    NumeroCommande    DateCommande    Etc
             1    1234              2013-04-01      Un
             2    2345              2013-07-14      Deux 

    Commandes actives :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '' AS 'COMMANDE_ACTIVE', * FROM COMMANDE_ACTIVE ;
    =>
    IdCommande    NumeroCommande    DateCommande    Etc
             1    1234              2013-04-01      Un

    Commandes archivées :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '' AS 'COMMANDE_ARCHIVEE', * FROM COMMANDE_ARCHIVEE ;
    =>
    IdCommande    DateArchivage
             2    2013-08-27 
    Et aussi :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '' AS 'COMMANDE_ARCHIVEE_V', * FROM COMMANDE_ARCHIVEE_V ;
    =>
    IdCommande    NumeroCommande    DateCommande    DateArchivage   Etc
             2    2345              2013-07-14      2013-08-27      Deux 

    La modélisation de la partie importation des commandes reste mystérieuse, merci de détailler la façon dont se passent les choses...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

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

Discussions similaires

  1. Gestion de commandes sous Access 2007
    Par Esquiss dans le forum Modélisation
    Réponses: 1
    Dernier message: 25/08/2008, 17h37
  2. Choix de technologies pour application de gestion de commandes
    Par jeffciara dans le forum Général Java
    Réponses: 2
    Dernier message: 14/01/2008, 09h18
  3. [USE CASE] Gestion de commande
    Par ducker88 dans le forum Cas d'utilisation
    Réponses: 9
    Dernier message: 06/02/2007, 09h20
  4. [Conception] Comment améliorer mon application de gestion de commandes ?
    Par etiennegaloup dans le forum Framework .NET
    Réponses: 5
    Dernier message: 09/08/2006, 18h54

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