Forum Programmation.SQL Modifier le schema dynamiquement

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
-1
9
déc.
2014

Bonjour,
Je travaille sur une appli où tous les mois on doit faire des calculs pour tous les élément d'une table et les stocker en base de données (MySQL).
Quel est le plus intéressant, modifier le schéma de la base, ajouter une colonne et y stocker le résultat des calculs ou crée une nouvelle table (id_objet, mois, résultat).
Il ne devrait pas être possible de pouvoir lancer les calculs plusieurs fois en même temps, il ne devrait donc pas y avoir de conflit quelque soit le modèle choisi.

Ça me fait bizarre de modifier le schéma (n'y a-t-il pas de risque de corruption des données ?) mais je ne m'y connais pas assez.

Merci d'avance.

  • # Ni l'un ni l'autre

    Posté par  . Évalué à 2.

    Au vu des colonnes choisies, à savoir :

    (id_objet, mois, résultat)

    il suffit d'insérer au fil des mois les résultats dans la même table, sans modifier sa structure (sinon mois deviendrait faux), ni créer de nouvelle table (sinon mois n'aurait plus de sens).

    Matricule 23415

    • [^] # Re: Ni l'un ni l'autre

      Posté par  . Évalué à 2.

      poussons l'idée un peu plus loin avec

      (id_objet, annee, mois, jour, resultat)

      comme ca tu peux tenir quelques années avec la meme table, et faire des stats descendant jusqu'au jour (si tu calcules le resultat chaque jour).

      • [^] # Re: Ni l'un ni l'autre

        Posté par  . Évalué à 1.

        poussons l'idée un peu plus loin

        Même constat dans mon commentaire en dessous.

        Matricule 23415

      • [^] # Re: Ni l'un ni l'autre

        Posté par  . Évalué à 3.

        voir même

        (id_objet, date, résultat)

        C'est alors à l'applicatif de définir la périodicité des calculs

    • [^] # Re: Ni l'un ni l'autre

      Posté par  . Évalué à 0.

      Je ne peux pas trouver mon reponse, pourquoi/?


      accessoire mobile pas cher
      housse iPhone 6 Plus

  • # Commentaire supprimé

    Posté par  . Évalué à 2.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: Table

      Posté par  . Évalué à 1.

      Hello,

      Clairement, avec les éléments que tu nous donnes, les deux approches sont faisables.

      Elles sont faisables, mais aucune ne me semble raisonnable, comme je disais dans mon commentaire ci-dessus :) Ca détruit l'intérêt de la colonne "mois" à chaque fois. Or, s'il est là, c'est qu'il y a peut-être une raison.

      A la limite, ce qui me semblerait raisonnable s'il y a besoin de stocker les résultats sur plus d'une année, c'est altérer la table une bonne fois pour toute, pour rajouter une colonne année (voir un vrai champ date au lieu de deux colonnes… mais bon :) ça, c'est que du design !)

      Là on pourrait éventuellement faire des stats en tranchant par mois, année, etc.

      Mais les deux autres options vont en dépit du bon sens d'une base de donnée à mon avis (je ne suis ni SGBD admin, ni dans la mouvance noSQL, donc je peux me gourer sur les tendances modernes, hein !).

      Matricule 23415

      • [^] # Commentaire supprimé

        Posté par  . Évalué à 1.

        Ce commentaire a été supprimé par l’équipe de modération.

        • [^] # Re: Table

          Posté par  . Évalué à -2.

          Ainsi, au bout de 10 ans, on est au mois 120

          Compter les mois en base 10, c'est rude. Très rude. Y'en a 12 quand même !

          Compter sans prévoir plus de 10 ans, c'est encore plus rude :)

          Je ne suis ni DBA ni le client final, mais je doute un peu de la manière de procéder, là. :p

          Matricule 23415

          • [^] # Commentaire supprimé

            Posté par  . Évalué à 2.

            Ce commentaire a été supprimé par l’équipe de modération.

            • [^] # Re: Table

              Posté par  . Évalué à -2.

              Moi pas comprendre ! Ca te gène de dire que 10 ans c'est 120 mois

              En base 10 comme proposée, oui, très fortement.

              Comment différencier octobre de l'an 0 (10) de janvier de l'an 1 (10) ? Par du padding ? Super pour les requètes SQL…

              Matricule 23415

              • [^] # Commentaire supprimé

                Posté par  . Évalué à 2.

                Ce commentaire a été supprimé par l’équipe de modération.

                • [^] # Re: Table

                  Posté par  . Évalué à -2. Dernière modification le 09 décembre 2014 à 23:59.

                  Je ne vois pas où est le problème ;)

                  Agrège moi les stats de janvier de toutes les années 0-9.

                  En SQL, hein ;)

                  Et déjà, tu vois que tu as un problème, tu dois passer à 13, et pas 12*10…

                  Matricule 23415

                  • [^] # Commentaire supprimé

                    Posté par  . Évalué à 1. Dernière modification le 10 décembre 2014 à 00:16.

                    Ce commentaire a été supprimé par l’équipe de modération.

                    • [^] # Re: Table

                      Posté par  . Évalué à -3.

                      Hello,

                      L'opérateur modulo est ton ami ;)

                      Allons-y alors. Je sens qu'on va se marrer, rien que juste le calendrier rien que Julien.

                      A toi l'honneur !

                      Y'a au moins quatre modulos à faire.

                      Tu voudrais un truc du genre YYYYM, où M est le mois, et YYYY des années ?

                      Non, je dis que c'est encore plus compliqué que ça.

                      Matricule 23415

                      • [^] # Commentaire supprimé

                        Posté par  . Évalué à 2.

                        Ce commentaire a été supprimé par l’équipe de modération.

                      • [^] # Commentaire supprimé

                        Posté par  . Évalué à 2.

                        Ce commentaire a été supprimé par l’équipe de modération.

                        • [^] # Re: Table

                          Posté par  . Évalué à -4.

                          avec une hypothèse : c'est que le mois de référence, c'est le mois de janvier de l'année 0.

                          Super. Ça ne me donne rien.

                          Donc ta somme fait les sommes quelques soient les années (en gros).

                          Moi je te demande le diff par années. Pour savoir si en hyper décideur je prend les bons choix.

                          Et j'ai toujours un doute sur ton SUM() mais bon.

                          Matricule 23415

                          • [^] # Commentaire supprimé

                            Posté par  . Évalué à 5.

                            Ce commentaire a été supprimé par l’équipe de modération.

  • # effaré

    Posté par  . Évalué à 2.

    Je suis pas un spécialiste, mais je lis les réponses et je suis effaré…. il est possible de faire avec le numéro de mois (relatifs), comme il est possible de faire avec une colonne année. Je vais prendre l'exemple du spécialiste qui nous explique qu'avec modulo c'est trop vachement compliqué, voir impossible.

    create table bar (`month` int, `number` int); 
    insert into bar values (1,50);
    insert into bar values (2,30);
    insert into bar values (13,30);
    insert into bar values (14,10);
    insert into bar values (15,14);
    insert into bar values (25,11);
    
    mysql> select * from bar;                
    +-------+--------+      
    | month | number |      
    +-------+--------+      
    |     1 |     50 |      
    |     2 |     30 |      
    |    13 |     30 |      
    |    14 |     10 |      
    |    15 |     14 |      
    |    25 |     11 |      
    +-------+--------+      
    6 rows in set (0.00 sec)
    
    # admettons que janvier soir le 1 (et donc le 13 et 25) et que l'on veuille tous les janvier 
    #(soit 50+30+11) 91 :
    
    mysql> select sum(number) from bar where (mod(month,12)=1 and month > 12) or month=1 ;
    +-------------+
    | sum(number) |
    +-------------+
    |          91 |
    +-------------+
    1 row in set (0.00 sec)

    Une seule requête.

    bonus, ca marche avec février 30+10=40

    mysql> select sum(number) from bar where (mod(month,12)=2 and month > 12) or month=2 ;
    +-------------+
    | sum(number) |
    +-------------+
    |          40 |
    +-------------+
    1 row in set (0.00 sec)

    Maintenant il faut voir la suite de l’application pour décider c'est bien ou pas, mais cela permet de faire des moyennes glissants facilement sur x mois consécutifs par exemple : where month in (25,26,27,28)…

    • [^] # Re: effaré

      Posté par  . Évalué à 1.

      Salut,

      Maintenant il faut voir la suite de l’application pour décider c'est bien ou pas,

      Béh oui. Mais si c'est une moyenne glissante, c'est différent d'une moyenne tout court.

      Mais pour l'instant on parle de modifier un schéma SQL.

      Encore une fois, je ne suis pas gestionnaire de SGBD :)

      Matricule 23415

      • [^] # Re: effaré

        Posté par  . Évalué à 2.

        je repose mon commentaire perdu dans les limbes…

        ajout : il y a aussi la moyenne par mois qui est une moyenne tout court…. c'est bonus la glissante.

        Je vais le faire par année :

        mysql> insert into bar values (27,10);
        Query OK, 1 row affected (0.00 sec)   
        
        mysql> select month,number,truncate(month/12,0) from bar;
        +-------+--------+----------------------+                
        | month | number | truncate(month/12,0) |                
        +-------+--------+----------------------+                
        |     1 |     50 |                    0 |                
        |     2 |     30 |                    0 |                
        |    13 |     30 |                    1 |                
        |    14 |     10 |                    1 |                
        |    15 |     14 |                    1 |                
        |    25 |     11 |                    2 |                
        |    27 |     10 |                    2 |                
        +-------+--------+----------------------+                
        7 rows in set (0.02 sec)                                 
        
        mysql> select month,sum(number),truncate(month/12,0) as annee from bar group by annee;
        +-------+-------------+-------+
        | month | sum(number) | annee |
        +-------+-------------+-------+
        |     1 |          80 |     0 |
        |    13 |          54 |     1 |
        |    25 |          21 |     2 |
        +-------+-------------+-------+
        3 rows in set (0.00 sec)

        et méga bonus

        mysql> select month,sum(number),2011+truncate(month/12,0) as annee from bar group by annee;
        +-------+-------------+-------+
        | month | sum(number) | annee |
        +-------+-------------+-------+
        |     1 |          80 |  2011 |
        |    13 |          54 |  2012 |
        |    25 |          21 |  2013 |
        +-------+-------------+-------+
        3 rows in set (0.00 sec)

        Et là on a la moyenne par année (janvier-décembre). on ne modifie pas un schéma de table à la volée,les BDD sont faite pour enregistré les données en LIGNES.

        Cela me déprime de lire tout et n'importe quoi sur des forums et des péquins sont renvoyés avec des fausses réponses en pensant parler à des mecs qui s'y connaissent un peu… c'est triste.

        Moi non plus je suis pas admin de BDD, mais je réponds pas à tort et à travers.

        • [^] # Re: effaré

          Posté par  . Évalué à -2.

          Hello,

          c'est bonus la glissante.

          C'est pas encore ça pour la glissante. Mais bon :)

          Disons que c'est mieux. Enfin, c'est infaisable en SQL… donc de toute façon…

          Matricule 23415

          • [^] # Re: effaré

            Posté par  . Évalué à 5.

            Q"est-ce qui est impossible à faire ?

            j'ai fais la somme pour que ce soit facile à lire, mais si met avg(), au lieu de sum(), tu auras la moyenne.

            Je crois qu'on ne se comprends pas.

    • [^] # Commentaire supprimé

      Posté par  . Évalué à 3.

      Ce commentaire a été supprimé par l’équipe de modération.

  • # modifier le schéma dynamiquement ou modifier le schéma tout court ?

    Posté par  . Évalué à 4.

    Il y a une petite ambiguïté sur le titre de ta question, et ce n'est pas anodin. Modifier le schéma (le faire évoluer ponctuellement pour faire face à des nouveaux besoins), c'est une opération relativement courante. Modifier dynamiquement le schéma (l'application utilise directement des commandes de DDL[1] pour modifier le schéma à la volée), c'est plutôt casse gueule.

    Dans ton cas, je pense qu'il s'agit de modifier ponctuellement la structure de la base de données. L'ajout d'une table ou d'un champ dans une table n'est a priori pas susceptible d'entraîner une corruption des données, ce qui n'interdit pas de faire une sauvegarde ponctuelle avant la modification (parce que c'est de toute façon une bonne pratique).

    Je trouve difficile de juger de la pertinence d'ajouter une colonne ou une table dans ton cas, parce que ça dépend des enjeux à long terme. Si la donnée calculée n'a vraiment de sens fonctionnel qu'à un instant T, donc que conserver les calculs des mois précédents n'a aucun intérêt, une simple colonne pourrait suffire. Si l'évolution de cette donnée dans le temps est fonctionnellement intéressante, ajouter une table peut être intéressant.

    Bref, modifier ponctuellement la structure de la base de donnée pour répondre à un nouveau besoin est une opération tout à fait classique. Les moteurs de gestion de base de données sont fait pour ça, pas de problème.

    Ajouter une table ou une colonne semblent permettre de répondre au besoin. Chaque solution a ses avantages et inconvénients.

    1.Ajout de colonne :

    • avantages :
      • structure de donnée plus simple
      • interface de visualisation des données plus simple
    • inconvénient :
      • idéalement, il faut trouver un moyen d'indiquer à l'utilisateur la date des derniers calculs, pour ne pas l'induire en erreur (par exemple en début de mois)
      • (inconvénient potentiel) pas d'historisation

    2.Ajout de table :

    • avantages :
      • données historisées
    • inconvénients :
      • structure plus complexe
      • (inconvénient potentiel) interface de visualisation plus complexe si on veut présenter les données historisées à l'utilisateur

    Re bref (hmmm pas si sûr que ça soit bref :D ) : Modifier la structure de donnée est une manipulation techniquement anodine. Dans ton cas, les deux solutions (ajout de table ou ajout de colonne) permettent une réponse technique à ta question. Du coup, le choix entre ces deux solutions ne peut pas se faire sur un critère purement technique. C'est donc en regardant le contexte global de l'application qu'il faudra choisir entre ces deux solutions.

    D'autre part, si les calculs sont suffisamment simples et les données pas trop volumineuses, un calcul à la volée à chaque consultation pourrait aussi peut-être répondre au besoin.

    Voilà, je suis tout à fait conscient que je n'ai absolument pas répondu à ta question (ou plutôt que je t'ai répondu de trouver la réponse tout seul ;) ) mais j'espère que tu trouveras quand même matière à réflexion dans ce commentaire.

    [1] point acronyme: le DDL (Data Definition Language) permet de modifier la structure d'une base de données. Le DML (Data Manipulation Language) permet de manipuler les données (insertion, modification, suppression, requête)

  • # Modifier le schema dynamiquement

    Posté par  . Évalué à 1.

    Bonjour,
    Je me rend compte que j'ai mal posé ma question.
    Le but est bien de faire la manipulation tous les mois dynamiquement.
    Les données calculées seront utilisées tous les mois pour le calcul suivant.

    • [^] # Re: Modifier le schema dynamiquement

      Posté par  . Évalué à 2.

      Le but est bien de faire la manipulation tous les mois dynamiquement.
      Les données calculées seront utilisées tous les mois pour le calcul suivant.

      ben tu fais une seule fois la table (id_objet,date, resultat)
      tu la remplie chaque mois avec les resultats precedents, selon la methode de la fenetre glissante decrite plus haut.

      • [^] # Re: Modifier le schema dynamiquement

        Posté par  . Évalué à 1.

        C'est bien ce que je pensais, la plupart des applications que j'ai pu voir faisait ainsi, mais je me demandais si c'était pour être le plus générique possible ou s'il y avait d'autres raisons, Sécurité, intégrité des données, performance, développement…

        • [^] # Re: Modifier le schema dynamiquement

          Posté par  . Évalué à 4.

          2 questions à ce poser,

          quel pourrait etre l'interet d'avoir 25 tables, qui contiennent toutes (id_objet, mois, données)
          et de devoir, dans ton code, calculer quelle table tu dois interroger en fonction de ce que demande l'utilisateur,
          d'autant plus complexe au changement, disons, d'année, ou tu vas avoir des données à cheval sur deux tables (année en cours, et année predecente)

          alors qu'une seule table contenant les 25 années (25x12 mois) te permet d'avoir un code qui dit juste "va chercher dans la table des resultats"

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.