Forum Programmation.SQL Stocker un tableau dans une base sql

Posté par .
Tags : aucun
0
21
déc.
2006
Bonjour,

J'ai une base de données MySQL et je stocke des données correspondant à des choix des utilisateur de mon site.

Actuellement, si un utilisateur choisi toutes les options de ma liste, j'enregistre une centaines d'entrées dans ma base de données.

Afin d'optimiser ma base, est 'il plus interressant de stocker un tableau avec l'enssemble des choix dans ma base. Ainsi, je n'aurais qu'une seule entrée enregistrée par utilisateur.

Si cela est possible, quelqu'un sait'il comment faire ?

Merci d'avance :)
  • # tout depend...

    Posté par . Évalué à 1.

    si c'est stocker une chaine genre
    paramettre=010100110011

    pour savoir sur les options sont actives ou pas, c'est dans ton programme que tu feras la decoupe de cette valeur.

    perso : je ferais une table mysql avec une colonne par option.
    ensuite les entrées et les modifications sur font par une seule requete qui modifie la liste des options en reprenant toutes les options du formulaire.
    • [^] # Re: tout depend...

      Posté par . Évalué à 1.

      Si ta liste d'options est fixe, alors le mieux est d'avoir un champ pour chaque. Sinon, soit tu restes avec une table pour faire les associations (user,option,value), soit tu bricoles en enregistrant une chaine du genre "var1=valeur&var2=valeur&...", mais attention à faire en sorte que ça reste compatible en ajoutant de nouvelles options.
      • [^] # Re: tout depend...

        Posté par . Évalué à 1.

        oki, pour plus de souplesse je vais faire une table user, une table choix et une association. Il y aura une entrée par choix et je ferais un index sur l'id du user ....
        • [^] # Re: tout depend...

          Posté par . Évalué à 1.

          je ferais une seule table config avec :
          IDuser, option1, option2, option3, etc etc

          la table user existant deja
          IDuser, nom, prenom, pseudo, telephone, etc etc
      • [^] # Re: tout depend...

        Posté par (page perso) . Évalué à 2.

        Si tu fait du php te prend pas la tête, sérialise l'array et met le dedans.

        Bon tu perd la possibilité d'éditer les valeur directement dans la db facilement a ce moment là.

        Mais le plus logique serait de faire un champ par paramètre, même un bête champ tinyint(1) pour mettre un bool dedans (NULL ou 1)
        • [^] # Re: tout depend...

          Posté par . Évalué à 2.

          ais le plus logique serait de faire un champ par paramètre, même un bête champ tinyint(1) pour mettre un bool dedans (NULL ou 1)


          c'est pas mieux de faire un champs BOOLEAN pour mettre un booleen dedans ?
          • [^] # Re: tout depend...

            Posté par (page perso) . Évalué à 1.

            Extrait du manuel MySQL:

            <<BOOL, BOOLEAN

            These types are synonyms for TINYINT(1).>>

            Donc la réponse est non,.
            En plus élaboré: C'est pas mieux, c'est pareil.
  • # Mauvaise idée.

    Posté par . Évalué à 6.

    Afin d'optimiser ma base, est 'il plus interressant de stocker un tableau avec l'enssemble des choix dans ma base. Ainsi, je n'aurais qu'une seule entrée enregistrée par utilisateur.


    En soi non, car tu brises le modèle relationnel et tu saisis une information qui n'est exploitable que par l'application (et difficilement éditable par le DBA, avec çà).

    Actuellement, si un utilisateur choisi toutes les options de ma liste, j'enregistre une centaines d'entrées dans ma base de données.


    Ce n'est pas forcément un problème. Dans le pire des cas, si tu répertories 1000 utilisateurs et qu'ils sélectionnent tous la totalité des options, tu obtiendras une table de 100 000 entrées. En considérant que tu utilises des IDs sur 32 bits pour coder ton numéro d'utilisateur comme ton numéro d'option, ta table atteindra péniblement les 800 Ko. Le moindre *.ogg traînant sur ton disque en fait minimum le triple ...

    D'autre part, si tu stockes tes infos dans un tableau, tu gagneras sur le l'ID utilisateur, certes (gain minimum de 50%), mais tu stokeras à chaque fois le tableau entier ! Ce qui revient précisément à faire ce que tu cherches à éviter.

    En outre, il faut garder à l'esprit que les informations des différents tuples sont stockées de manière contigüe sur ton disque. Donc stocker un tableau de dix entiers dans un enregistrement ou insérer dix entrées dans une table d'une colonne de type entier va se traduire exactement de la même façon sur ton support.

    C'est le mauvais coté de la programmation orientée objet, d'ailleurs. On considère l'entité en tant que telle mais on en oublie sa nature, et on devient beaucoup plus sensible au cardinal de son ensemble qu'à son coût unitaire en ressources.

    La seule chose qui va être déterminante dans le choix de l'architecture de ta base est la distribution de tes données dans le sens statistique du terme. Nombre d'utilisateurs à choisir des options, nombre moyen d'options sélectionnées par utilisateurs, scoring de tes options (important) : est-ce que 80 % des utilisateurs sélectionnent 20 % des options proposées ou bien est-ce uniformément réparti ? etc.

    Par contre, l'intérêt du champ unique est d'éviter d'avoir à recourir à une boucle Fetch(). Certains langages permettent de charger un resultset en une opération mais, bien souvent; celle-ci est implémentée à son tour par une boucle dans le niveau d'abstraction immédiatement inférieur, donc le gain n'est pas réel. En transférant le tout d'un coup tu réduis de manière significative le trafic réseau et la charge système. Par contre, ce n'est palpable que si tu fais la même opération pour des centaines d'utilisateurs à la suite.

    En résumé, cela peut-être efficace d'un point de vue technique pure, à condition de rester dans un système statique. Si tu veux par exemple faire évoluer ta base et empêcher certains utilisateurs de sélectionner certaines options, tu pourras aisément poser une contrainte d'intégrité pour que le SGBD rejette les entrées illégales. Si tu utilises un format particulier, tu court-circuites ces fonctionnalités et tu restes donc seul garant de la cohérence de ta base.

    Bon courage.
    • [^] # Re: Mauvaise idée.

      Posté par . Évalué à 2.

      bien ecrit et comprehensible
      +1
    • [^] # Re: Mauvaise idée.

      Posté par (page perso) . Évalué à 3.

      Bonsoir,

      Je profite de cette compétence éprouvée pour poser une question qui me tulupine depuis quelques temps :

      Dans la question de vérification d'intégrité par la base de donnée avec des contraintes, la base rejetant les enregistrements fautifs, il faut que le code "capture" le rejet de la base et l'analyse pour expliciter le pourquoi du rejet à l'utilisateur.

      N'est-il pas plus facile et plus performant en terme de rapidité de vérifier l'intégrité par le code AVANT insertion, plutôt que de faire un système de gestion d'erreur qui explique ensuite pourquoi la commande n'a pas été effectuée et a été rejetée ?

      Poser de manière plus perverses ;-) Le fait de gérer par le sgbd l'intégrité et laisser le codeur bidouiller pour expliciter les 'erreurs/rejets' d'intégrité est une manière de ne pas dépendre du codeur pour l'intégrité (par exemple dans des applis critiques ou il vaut mieux que ca marche pas sans explications plutôt que ca marche alors qu'il ne faut pas) ?
      • [^] # Re: Mauvaise idée.

        Posté par . Évalué à 1.

        Dans la question de vérification d'intégrité par la base de donnée avec des contraintes, la base rejetant les enregistrements fautifs, il faut que le code "capture" le rejet de la base et l'analyse pour expliciter le pourquoi du rejet à l'utilisateur.


        oui ! Si t'arrives à faire ça, c'est cool =)
        De ce que j'ai vu, le plus souvent, l'analyse de l'erreur se résume à "database error" ou "inconsistent data", pis après, démmerde toi ... :/

        N'est-il pas plus facile et plus performant en terme de rapidité de vérifier l'intégrité par le code AVANT insertion, plutôt que de faire un système de gestion d'erreur qui explique ensuite pourquoi la commande n'a pas été effectuée et a été rejetée ?


        Excellente question. Pour moi, ça dépend de tes données. Si statistiquement, les incohérences des données en entrée sont rares, la majorité de tes tests d'intégrité en amont ne servira à rien donc tu perds en perfo si tu testes tout avant. Si tes données en entrée sont très souvent moisies, ça peut valoir le coup de faire tes tests de diagnostic avant de tenter l'insertion.
        Comme pour *toutes* les questions de perfo, il faut benchmarker avec des données et des volumétrie de prod.

        il vaut mieux que ca marche pas sans explications plutôt que ca marche alors qu'il ne faut pas ?


        alors là, une seule réponse possible, si les données sont foireuses, il ne faut *pas* que ça marche. La correction (le fait de se comporter correctement) d'un logiciel est une de ses qualités essentielles. Pourquoi ? parce que l'erreur se propage. Si une brique de ton soft laisse passer des données incohérentes, l'incohérence se propage dans tout le reste du soft, et tu as vite fait de te retrouver avec une base de données indémmerdable (données contradictoires, incomplètes, fausses, doublons fonctionnelles, ...) qui entraîne des plantages applicatifs (à moins que le soft ait été codé dès le départ en postulant que les données en base n'étaient pas fiables, et encore ...)

Suivre le flux des commentaires

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