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

Requêtes MySQL Discussion :

[Questionnaire] - Mieux vaut une table avec 30 colonnes ou enormement de lignes ?


Sujet :

Requêtes MySQL

  1. #1
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut [Questionnaire] - Mieux vaut une table avec 30 colonnes ou enormement de lignes ?
    Bonjour tout le monde,
    J'espere que vous allez bien.
    J'ai un questionnaire avec 30 questions (le nombre ne changera pas dans le futur, c'est surtout utilisé pour un sondage).

    Alors j'ai utilisé le modèle suivant :

    Une table Participant( ID_Participant, Nom_Participant)
    Une table Question( ID_Question, Intitulé_Question)
    Une table Reponse( ID_Reponse, Intitulé_Reponse)
    Une table Traitement( ID_Participant, ID_Question, ID_Reponse)

    A chaque fois qu'un partipant a fini de remplir le questionnaire, la table Traitement grossit de 30 lignes.

    Mais voila, en voyant large je me suis dit que si 100.000 personnes rempli le questionnaire alors il y aura 3 Millions de lignes !
    Alors que si je fais tout simplement 30 colonnes dans une seul table (1 colonne par question) je n'aurais que 100.000 lignes.

    Maintenant voila le cas de figure, que faut t'il faire dans mon cas si jamais on vise 100.000 personnes qui remplit le questionnaire ? Jouer ca sur 30 colonnes ou bien la premiere solution est plus simple ? et pourquoi ?


    Merci d'avance.

    ++
    ShinJava

  2. #2
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Salut.

    Si on part de l'hypothèse que :

    - ID_Participant : 4 octets
    - ID_Question : 1 octet (s'il n'y en a que 30)
    - ID_Reponse : 1 octet

    Et que mes calculs sont corrects, on arrive à un peu plus de 17 Mo pour la table Traitement si 100 000 participants répondent. Il n'y a pas de quoi s'inquiéter !

    Si tu choisis ta structure de 30 colonnes, tu gagnes pas mal de place. Et si c'est certain que le formulaire reste fixe, ça peut valoir le coup d'avoir une si mauvaise structure de base de données

    Après, il faut quand même voir les requêtes que tu fais. Si tu fais souvent des SELECT sur la table des participants, c'est dommage de la surcharger autant avec toutes les réponses.

    Si tu fais des traitements (ex : statistiques), tu peux les enregistrer dans une table à part régulièrement et donc éviter de les regénérer à chaque fois que quelqu'un veut les voir.

    Tout ça dépend donc de l'utilisation de ta base de données !

  3. #3
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut
    Salut,
    Merci pour ta réponse et tes précisions !

    Si tu choisis ta structure de 30 colonnes, tu gagnes pas mal de place.
    C'est à dire ? au niveau du disque dur ou autre chose ? (désolé si la question semble naïf)


    Niveau statistique, ca sera generé à chaque fois qu'une personne aura rempli le formulaire (plusieurs select selon plusieurs critères pour avoir plusieurs statistiques différentes).

    Je suis tenté par la première solution, mais ce qui me fait le + peur c'est le million de lignes.
    Maintenant, en terme de performance (que ce soit des insert, select ou autre) et en stabilité de la table, est-ce que le nombre de lignes est pris en compte ?
    Les rêquetes sont-elles moins efficaces quand on est face a plusieurs colonnes ou a plusieurs lignes ?

    Merci d'avance

    ++
    ShinJava

  4. #4
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Citation Envoyé par ShinJava
    C'est à dire ? au niveau du disque dur ou autre chose ? (désolé si la question semble naïf)
    Oui au niveau du disque dur. Et par conséquent, il y a de grandes chances que la RAM du serveur soit moins solicitée lors de l'exécution de certaines requêtes.

    Citation Envoyé par ShinJava
    Niveau statistique, ca sera generé à chaque fois qu'une personne aura rempli le formulaire (plusieurs select selon plusieurs critères pour avoir plusieurs statistiques différentes).
    Tu veux dire que s'il y a 100 000 participants, il n'y aura de toute façon que 100 000 générations des stats ? Dans ce cas, je te suggère de garder une structure propre. Car si ta génération de stats est ralentie à la fin, ça sera l'histoire de quelques secondes seulement !

    Citation Envoyé par ShinJava
    Maintenant, en terme de performance (que ce soit des insert, select ou autre) et en stabilité de la table, est-ce que le nombre de lignes est pris en compte ?
    Plus les tables sont remplies, plus certaines requêtes sont lentes à exécuter. Pour les SELECT, c'est (presque) toujours le cas. Pour les INSERT, je crois que ça n'a quasi aucune influence. En fait, c'est surtout les conditions de restriction (WHERE x=...) qui vont être de plus en plus lentes, que ça soit pour un SELECT, UPDATE ou DELETE.

    Citation Envoyé par ShinJava
    Les rêquetes sont-elles moins efficaces quand on est face a plusieurs colonnes ou a plusieurs lignes ?
    Oui, le nombre de colonnes influence également les performances des requêtes. Peut-être moins que le nombre de lignes. Mais là aussi, il faut surtout regarder le type des requêtes fréquentes.

    Sinon, un truc qui me choque un peu dans le schéma que tu as proposé dans ton premier post, c'est que les réponses ne sont jamais reliées aux questions. A moins que toute réponse soit valide pour toute question ?

  5. #5
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut
    Merci encore pour tes précisions, je vais m'orienter vers la premiere solution qui est quand même la plus propre.

    Sinon, un truc qui me choque un peu dans le schéma que tu as proposé dans ton premier post, c'est que les réponses ne sont jamais reliées aux questions. A moins que toute réponse soit valide pour toute question ?
    Ah je vois ce que tu veux dire, pour moi les questions - réponses étaient reliés dans la table Traitement.

    Tu penses qu'il serait plus simple et plus optimisé de faire comme ce qui suit :

    Une table Participant( ID_Participant, Nom_Participant)
    Une table Question( ID_Question, Intitulé_Question)
    Une table Reponse( ID_Reponse, Intitulé_Reponse)
    Une table RelationQR(ID_RelationQR, ID_Question, ID_Reponse)
    Une table Traitement( ID_Participant, ID_RelationQR)

    Du coup la table Traitement devient un peu plus légère ?

    Merci d'avance

    ++
    ShinJava

  6. #6
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Il y a deux problèmes à mon goût dans ton schéma initial, sans le lien entre questions / réponses possibles.

    - Il est possible d'enregistrer dans Traitement, un couple (ID_Question, ID_Réponse) qui est incorrect, c'est-à-dire qui n'est pas normalement prévu par ton formulaire.

    - Il y a de la redondance dans Traitement. Si cent participants choisissent la réponse n°6 à la question n°2, on répète cent fois le couple (6,2). S'il est lié ailleurs, on ne le fait qu'une fois.

    De plus, ton schéma ne permet pas une génération automatique du questionnaire. Dans ton cas, cela n'est pas intéressant. Mais dans d'autres, ça peut faciliter les mises à jour et autres modifications dans la base des questions.

    Citation Envoyé par ShinJava
    Tu penses qu'il serait plus simple et plus optimisé de faire comme ce qui suit :

    Une table Participant( ID_Participant, Nom_Participant)
    Une table Question( ID_Question, Intitulé_Question)
    Une table Reponse( ID_Reponse, Intitulé_Reponse)
    Une table RelationQR(ID_RelationQR, ID_Question, ID_Reponse)
    Une table Traitement( ID_Participant, ID_RelationQR)
    A ta place, je ferais plutôt le lien directement dans Reponse. Car il s'agit d'une relation 1,1 (une réponse ne concerne qu'une et une seule question).

    Donc :

    Une table Participant( ID_Participant, Nom_Participant)
    Une table Question( ID_Question, Intitulé_Question)
    Une table Reponse( ID_Reponse, ID_Question, Intitulé_Reponse)
    Une table Traitement( ID_Participant, ID_Reponse)

    L'inconvénient par rapport à ton ancienne table traitement : une jointure entre Traitement et Reponse pour avoir le numéro de la question. Mais la table Reponse n'étant sûrement pas très "grosse", il n'y aura pas beaucoup de répercutions sur la vitesse de traitement.


    Citation Envoyé par ShinJava
    Du coup la table Traitement devient un peu plus légère ?
    En effet, si on prend toujours 4 octets pour l'ID du participant et 1 pour l'ID de la réponse, tu arrives à 14Mo au lieu des 17 pour 3M enregistrements

  7. #7
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut
    Je te remercie pour toute ces précisions, je saisi beaucoup mieux la chose maintenant.

    Par contre, désolé de t'embeter une derniere fois, mais dans ce schema je ne vois pas comment jvais gérer les SELECT. Avec une trentaine de colone c'était jouable avec les AND et OR dans la clause WHERE mais là ...

    Par exemple pour la table Traitement (ID_Participant, ID_Reponse) on a ces chiffres fictifs :
    1 2
    1 3
    1 4
    ....
    2 2
    2 4

    Comment je fais pour afficher uniquement les participants qui ont choisi dans ID_Reponse la 2 et 3 par exemple ?
    Je ne vois pas trop comment m'en sortir, en essayant avec OR ca m'affiche tout ceux qui ont choisi 2 ou 3.

    Merci d'avance


    ++
    ShinJava

  8. #8
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Citation Envoyé par ShinJava
    Comment je fais pour afficher uniquement les participants qui ont choisi dans ID_Reponse la 2 et 3 par exemple ?
    Ce n'est pas le genre de requêtes que j'affectionne
    Je pense qu'il y a beaucoup mieux que ma réponse (qui n'est pas juste si ça se trouve), mais la voilà quand même.

    Un moyen simple est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT t1.ID_Participant
    FROM Traitement t1 JOIN Traitement t2 ON t1.ID_Participant = t2.ID_Participant
    WHERE t1.ID_Reponse = 2 AND t2.ID_Reponse = 3
    Ou sinon, quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT ID_Participant
    FROM Traitement
    WHERE ID_Reponse = 2
    AND ID_Participant IN (
          SELECT ID_Participant
          FROM Traitement
          WHERE ID_Reponse = 3 )
    Je cherche quelque chose de mieux, mais pour l'instant je sèche comme toi Si ça peut déjà te donner quelques idées.

  9. #9
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut
    Depuis tout à l'heure j'epluche les docs, je cherche, mais je trouve pas grand chose.
    En tout cas tes requêtes fonctionne bien. Mais si tu as quelques chose de mieux , je suis effectivement preneur.
    Je continu à chercher de mon côté voir s'il y a plus simple.

    En tout merci encore pour ta patience et de m'avoir éclairer sur plusieurs points.

    ++
    ShinJava

  10. #10
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Voilà ce que je viens de pondre. Ca a l'air de fonctionner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT ID_Participant
    FROM Traitement
    WHERE ID_Reponse = 2
    OR ID_Reponse = 4
    GROUP BY ID_Participant
    HAVING COUNT(ID_Reponse) = 2
    Ici, tu peux rajouter autant de "OR ID_Reponse=x" que tu veux et après modifier le "COUNT(ID_Reponse)=2" pour mettre le nombre total d'ID_Reponse que tu as spécifié plus haut. C'est donc plus facile à générer dynamiquement que les précédentes !

    Edit : Et bien sûr, tous ces OR peuvent être écrits plus simplement avec "WHERE ID_Reponse IN (2, 3, ...)"

  11. #11
    Membre averti Avatar de ShinJava
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    413
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 413
    Points : 357
    Points
    357
    Par défaut
    Genial !!!
    Ca marche nickel. Tu m'as pondu un code assez simple et facilement customizable.
    Merci beaucoup pour toute l'aide que tu m'as apportés. Avec ca je vais pouvoir avancer sereinement.
    Merci encore !
    Je te souhaite de passer une bonne nuit.

    ++
    ShinJava

  12. #12
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Pas de problème
    Bonne continuation, et bonne nuit à toi aussi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/02/2015, 10h50
  2. créer une table avec des colonnes de types différents
    Par d_hazem dans le forum Composants
    Réponses: 1
    Dernier message: 15/01/2009, 15h23
  3. Réponses: 3
    Dernier message: 16/04/2008, 08h39
  4. [Oracle] Mieux vaut une grosse table ou plein de petite ?
    Par ShinJava dans le forum PHP & Base de données
    Réponses: 16
    Dernier message: 30/11/2005, 16h32
  5. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25

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