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 :

construire une table mysql pyramidale


Sujet :

Modélisation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Par défaut construire une table mysql pyramidale
    Bonjour. J'ai besoin d'un avis avisé. Je veux refaire ma base stock mais elle comprend des articles physique et virtuel. Jusque là tout va bien. Ce n'est pas dure. Mais je veux un effet "cascade" ou "pyramidale". Je prends un exemple pour mieux expliquer:

    Je prends l'article virtuel salon
    Dans salon je veux des articles Prises de courant, interrupteur virtuel aussi
    Sachant que prises de courant comprend la prise, le fil et le disjoncteur physique
    et que interrupteur comprend 2 va et vient, fil, disjoncteur physique

    Dans un masque pour faire mon devis il me faut en titre
    SALON
    puis en articles Prises de courant, interrupteur Mais le prix au bout est calculé en fonction des articles physiques que j'ai rentré.

    Je pense qu'il me faut donc une indexation commune pour entrer tout ça dans mon devis car c'est pour ne pas tout mélanger .
    Peut-on faire une colonne id autoincrémentée qui serait commune à tout ça.

    Comme vous le voyez, j'ai bien du mal. Pourtant je l'ai fait, mais ça ne fonctionne pas bien, et c'est tellement compliqué que je me prends le choux. Je serais bien preneur de bonnes idées voir d'un arrangement mysql que je ne connaitrais pas.

    J'ai plusieurs tables car la dénomination "prise de courant" est commune à 3 articles.
    Dans ces 3 articles il y en a 2 qui sont commun avec "interrupteur".

    J'ai une table pour les intitulés jointe à un groupe d'articles virtuels (2e table) qui sont eux même joint à une table stock physique (3e table) qui est gérée à part.
    Mais l'article "salon" fait partie de la table pour les intitulés qui est jointe à la 2e table. Et c'est là que ça devient dure.....

    Je ne vais pas expliquer mon sac d'embrouille, j'aimerais repartir sur des idées neuves voir mieux structurées. Si quelqu'un pouvait m'orienter autrement, je pourrais retravailler la chose.
    Je vous remercie de votre attention.

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Vous pourriez poster votre modèle actuel. Cela nous aiderait à bien comprendre vos besoins, et à vous orienter.


    Citation Envoyé par LampeRouge Voir le message
    Je ne vais pas expliquer mon sac d'embrouille, j'aimerais repartir sur des idées neuves voir mieux structurées. Si quelqu'un pouvait m'orienter autrement, je pourrais retravailler la chose.
    De ce que j'ai compris de votre explication, il me semble qu'il vous faudrait, dans les grandes lignes :
    1/ 1 table article, contenant tous les articles (Physiques et virtuels)
    2/ 1 table d'association Article_Article indiquant quels articles en composent un autre

    pour le 1/, vous devriez jeter un oeil sur cet article parlant de l'héritage, et qui correspond à ce que vous pressentiez :
    Citation Envoyé par LampeRouge Voir le message
    Je pense qu'il me faut donc une indexation commune pour entrer tout ça dans mon devis car c'est pour ne pas tout mélanger .
    Peut-on faire une colonne id autoincrémentée qui serait commune à tout ça.
    En deux mots, si vos articles physiques possèdent des propriétés qui leur sont propres (comme un prix par exemple, les articles virtuels n'ont pas de prix j'imagine ?), et/ou réciproquement, vous devriez envisager une table ArticlePhysique et une table ArticleVirtuel, héritant de la table article.
    Sur ce principe, la table Article_Article pourrait devenir ArticleVirtuel_Article.

    Par ailleurs, il semble que vous soyez en présence d'une arborescence : un article A(virtuel) peut être composé d'un article B(virtuel) lui-même composé des articles C et D (physiques). Si la profondeur de cette arborescence n'est pas finie, alors :
    A/ Attention, MySQL ne gère pas les requêtes récursives, peut-être pourriez vous envisager l'utilisation d'un autre SGBDR ?
    B/ Sinon, jetez un œil sur cet article également pour la représentation de votre arborescence.
    Cela facilitera les requêtes comme celles vous permettant de connaitre le prix d'un article virtuel (somme des prix*quantité de chaque article physique qui le composent).

  3. #3
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    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 218
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par aieeeuuuuu Voir le message
    Attention, MySQL ne gère pas les requêtes récursives, peut-être pourriez vous envisager l'utilisation d'un autre SGBDR ?
    Inutile d’envisager de changer de SGBD pour ce seul motif ! Certes, MySQL ne gère pas la jointure récursive en mode natif, mais il est très simple de pallier, au moyen d’une procédure récursive.

    Pour reprendre l’exemple du comptage des rivets par aile d’avion, certes la jointure récursive native est moins bavarde (cf. l’exemple proposé il y a 20 ans par Don Chamberlin), néanmoins voici un moyen de s’en sortir facilement ( et récursivement) avec MySQL :


    -- -----------------------------------------------------
    -- TABLE COMPOSANT
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS COMPOSANT 
    (
      EnsembleId       VARCHAR(10)     NOT NULL,
      EnsembleParent   VARCHAR(10)     NOT NULL,
      Quantite         INT             NOT NULL,
      PRIMARY KEY (EnsembleId, EnsembleParent)
    ) ;
    
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('rivet', 'longeron', 10) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('rivet', 'aileron', 5) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('rivet', 'aile', 100) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('rivet', 'charnière', 4) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite)  VALUES ('rivet', 'train', 8) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('aileron', 'aile', 1) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite)  VALUES ('charnière', 'aileron', 2) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('charnière', 'train', 3) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('longeron', 'aile', 5) ;
    INSERT INTO COMPOSANT (EnsembleId, EnsembleParent, Quantite) VALUES ('train', 'aile', 1) ;
    
    SELECT * FROM COMPOSANT ;
    
    -- -----------------------------------------------------
    -- TABLE PILE - Simulation de la jointure récursive 
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS PILE 
    (
          PileId        INT            NOT NULL AUTO_INCREMENT,            
          Niveau        INT            NOT NULL,
          EnsembleId    VARCHAR(10)    NOT NULL,
          Quantite      INT            NOT NULL
     , PRIMARY KEY (PileId)   
    ) ;
    
    COMMIT ;
    
    DROP PROCEDURE IF EXISTS RecursonsJoyeusement ;
    
    DELIMITER GO
    
    CREATE PROCEDURE RecursonsJoyeusement
    (
       IN Amorce BOOLEAN, EnsembleIdIn VARCHAR(10),
       OUT totalOut INT
    )
    
    BEGIN
    
        DECLARE theEnsembleId VARCHAR(10) DEFAULT NULL ;
        DECLARE theNiveau INT DEFAULT 0;
        DECLARE Kount INT ;
     
        SET theNiveau = (SELECT DISTINCT coalesce (MAX(Niveau) + 1, 1) FROM PILE) ;
     
        IF Amorce = true 
            THEN
                INSERT INTO PILE (EnsembleId, Quantite, Niveau) 
                    SELECT EnsembleId, Quantite, TheNiveau  
                    FROM   COMPOSANT
                    WHERE  Ensembleparent = EnsembleIdiN ;
    
                SET totalOut = 0 ;
    
                CALL RecursonsJoyeusement(false, '', totalOut) ;
        ELSE
            SET Kount = (SELECT COUNT(*) 
                         FROM  (SELECT x.EnsembleId, x.Quantite, Niveau  
                                FROM   COMPOSANT AS x INNER JOIN PILE AS y 
                                       ON x.Ensembleparent = y.EnsembleId
                                WHERE  Niveau = TheNiveau - 1) as truc) ;
            IF Kount > 0 THEN
                INSERT INTO PILE (EnsembleId, Quantite, Niveau) 
                    SELECT x.EnsembleId, x.Quantite * y.Quantite, TheNiveau  
                    FROM   COMPOSANT AS x INNER JOIN PILE AS y ON x.Ensembleparent = y.EnsembleId 
                    WHERE  Niveau = TheNiveau - 1 ; 
    
               CALL RecursonsJoyeusement(false, '', totalOut);
            END IF ;
       
            SET totalOut = (SELECT SUM(Quantite) FROM PILE WHERE EnsembleId = 'rivet') ;
    
       END IF;
    
    END
    
    GO
    
    DELIMITER ;
    
     SET @@GLOBAL.max_sp_recursion_depth = 4;
     SET @@session.max_sp_recursion_depth = 4; 
    
    SET @entree := 'aile' ;
    SET @Amorce  := true ;
    
    CALL RecursonsJoyeusement(@Amorce, @entree, @total);
    
    SELECT 'Le grand total des rivets de ', @entree, ' : ',  @total; 
    Comme dans l'exemple de Chamberlin, le nombre de rivets utilisés pour une aile d'avion est toujours égal à 183...

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Bonsoir,
    Inutile d’envisager de changer de SGBD pour ce seul motif !
    Ça parait en effet un peu léger comme motif, j'en conviens. J'en vois bien d'autres, mais ce serait - en plus de subjectif - a coté du sujet...

    Simplement, comme LampeRouge semble être en train de revoir complètement son système, j'y vois pour lui l’occasion de faire d'une pierre deux coups.
    Je veux refaire ma base stock
    S'il s'agit juste de modifier une sous partie d'un existant déjà bien en place, alors effectivement, gardons MySQL et récursons joyeusement

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/05/2010, 10h41
  2. Vider une table MySQL suite à javascript:confirm()
    Par anutka dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 16/09/2005, 12h16
  3. Connaître le type d'un champs d'une table Mysql
    Par xoran dans le forum Langage SQL
    Réponses: 1
    Dernier message: 20/07/2005, 09h29
  4. Comment importer un document CSV dans une table MySql ?
    Par magic8392 dans le forum Requêtes
    Réponses: 6
    Dernier message: 04/02/2005, 11h03

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