Question d'analyse

Eléphant du PHP | 74 Messages

22 sept. 2008, 12:01

Hello,

J'ai une petite question d'analyse avant de me lancer dans mon projet.

J'ai une table client importante (environ 7 millions de ligne et 150 colonnes) En plus de cette table je doit créer une table qualif (qualifiant plus précisément les clients). Mais je ne sais pas comment créer cette nouvelle table. Le plus logique serait d'avoir une colonnes par qualification et une ligne par client. Mais il y a plus de 700 qualificatifs dont la grande majorité seront null. J'ai donc eu l'idée de transposer cette table en ligne de 3 colonnes (id_client, nom_qualif, valeur qualif) et ne créer la ligne que si la valeur_qualif est non null.

Il y a donc 2 solutions :
- 2 tables reliés en 1<->1 avec 150 colonnes d'un coté et 700 colonnes de l'autre multiplié par 7 millions de ligne
- 2 tables reliés en 1<->n avec 150 colonnes d'un coté multiplié par 7 million de ligne et 3 colonnes de l'autre multiplié par (je pense 100 millions de lignes)


Mais pour ces 2 solutions je n'arrive pas à cerner les avantages et inconvénient pour mes futurs requetes d'extraction de donées et surtout pour la perfomance de celle ci.
Mon nez me dit que ce n'est pas bon de transposer en colonnes. Mais comment mysql va t'il gérer 700 colonnes

Et votre nez il dit quoi :?

Merci
Mon projet opensource de gestion de Devis, Commandes, Factures, pour TPE : OpenDCF : http://opendcf.1g6.biz

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 sept. 2008, 13:39

Pour moi la règle est simple :

- Si 1 client à 0 ou 1 qualif :
client(id_client, fk_id_qualif#)
qualif(id_qualif, libelle_qualif)

- Si 1 client à 0 ou n qualif :
client(id_client)
possede(fk_id_client#, fk_id_qualif#)
qualif(id_qualif, libelle_qualif)

That's all, ensuite tes requêtes seront faciles à faire.

Eléphant du PHP | 422 Messages

23 sept. 2008, 18:01

Mais comment mysql va t'il gérer 700 colonnes
MySQL à la limite pas trop mal, mais tout ce qui va autour risque d'avoir du mal.

J'ai une table toute simple de réponse à un sondage de 550 questions avec une colonne par question, pas de jointure et également pas mal de colonnes à null. Quand je fais un "select * from sondage where id=y" pour afficher les réponses du sondé, ça va encore.
Mais
- affichage avec PhpMyAdmin : c'est quasiment impossible
- export : ça rame sec mais on y arrive, à condition de ne pas exporter sous Access qui n'accepte que 255 colonnes par table.

Pour arriver à manipuler plus aisément les résultats une fois le sondage terminé, je dispatche les résultats en 5 ou 6 tables d'une centaine de colonnes (create table extrait1 as select q1, q2, ... from sondage) selon les thèmes afin que la personne chargée de l'analyse puisse faire des requêtes
soit sur une table avec un extrait de colonne pour des études ciblées sur un thème
soit sur des jointures entre tables pour des études transverses sur 2 ou 3 thèmes.

Autre point : la conception et le développement ont été faits sur une version 5 de MySQL. La mise en prod s'est faite sur une version 3 !!! Aïe aïe aïe ...
Voila mon expérience.

Eléphant du PHP | 254 Messages

23 sept. 2008, 18:08

Ben comme le dit ouckileou, faut que tu simplifie le truc, avec une table client, une table avec toute les qualif possibles, et une table qui fait la liaison, ça t'éviterais les usines a gaz

Client
idclient
tous les champs qui vont bien

Qualification
idqualif
label de la qualif

ClientQualif
idqualif
idclient

L'existence d'un enregistrement signifierait que le cleint a cette qualif

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

24 sept. 2008, 00:01

[...]
Autre point : la conception et le développement ont été faits sur une version 5 de MySQL. La mise en prod s'est faite sur une version 3 !!! Aïe aïe aïe ...
Voila mon expérience.
Désolé mais ton exemple n'est pas significatif car avoir une colonne par question est une très mauvaise idée. Tu peux te dire que dès que tu as des colonnes redondantes dans une table, c'est que c'est mal conçu.

Il semblerait bien plus logique d'avoir une table "question".

De même, éclater les résultats dans des tables différentes n'a aucun sens, une table est une structure, pas "un bout" de données (je ne sais même pas comment dire)

La conception d'une donnée est normalisée, on la suit ou on ne la suit pas, mais ne pas la suivre pour des questions de performances est perdu d'avance. Car il viendra un jour où il y aura des informations supplémentaires à stocker, ou des requêtes différentes à effectuer, et ce sera forcément plus compliqué dans ce cas là.

Bien concevoir son modèle, choisir les bons types de données, utiliser le SQL correspondant à ce que l'on veut faire, mettre les index au bon endroit, réfléchir sur les algos, ça ça joue sur les perfs :)

Eléphant du PHP | 422 Messages

25 sept. 2008, 09:20

Désolé mais ton exemple n'est pas significatif car avoir une colonne par question est une très mauvaise idée. Tu peux te dire que dès que tu as des colonnes redondantes dans une table, c'est que c'est mal conçu.

Il semblerait bien plus logique d'avoir une table "question".

De même, éclater les résultats dans des tables différentes n'a aucun sens, une table est une structure, pas "un bout" de données (je ne sais même pas comment dire)
Désolé, je ne vais pas rentrer dans les détails du projet "sondage" que j'ai évoqué (ce n'est ni le lieu ni le moment), sache seulement que le choix de cette option de conception a été effectuée après étude de différentes possibilités, leurs avantages et leurs inconvénients et que les "bouts de table" qui n'ont pas de sens pour toi en ont un pour le statisticien avec lequel ils ont été définis.

Oui, dans la majorité des cas, la normalisation des données est la meilleure solution possible. Mais dans des cas atypiques (et ces données de pierreC avec 700 colonnes et ses 7 millions de ligne) en est un, il est extrêmement dangereux d'affirmer péremptoirement "il faut faire çi ou il faut faire ça" et d'appliquer sans réfléchir des recettes toutes faites sans connaître les tenants et les aboutissants de son projet. Ayant trop peu d'éléments d'analyse en ma possession, je me garderai donc -pour ma part- de lui préconiser une solution.

Ma réponse à sa question a seulement été un retour d'expérience pour lui dire "oui, des tables avec 700 colonnes sous MySQL, ça fonctionne. Mais il peut y avoir des problèmes".

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

25 sept. 2008, 11:09

Je ne voulais pas être péremptoire. Je n'applique pas non plus "des recettes toutes faites sans réfléchir".

C'est juste j'ai déjà lu des histoires comme ça, dont l'auteur nous assure que le fait d'avoir fait un schéma bizarre était complètement justifié. Sauf que j'attends toujours d'avoir un exemple concret.

Pareil, l'incursion du statiticien dans ton exposé ne me convainc pas puisque je ne doute pas que des extraits de sondage puisse avoir un sens pour lui, par contre je doute de l'utilité d'avoir une table par "extrait". À ma connaissance, ce n'est pas l'utilisateur qui se charge la modélisation de ta base.

Mais bon soit, je n'en connais pas assez sur ton outil et je te laisse le bénéfice du doute. Concernant le projet du posteur de ce sujet, il faudrait des retours maintenant.

Et je n'ai pas dit que ton intervention était inutile, je rebondissais juste sur cette histoire de modélisation qui, à mon sens, est très importante.

ViPHP
ViPHP | 5924 Messages

25 sept. 2008, 16:16

Un statisticien n'est pas un informaticien, t'autant plus en bases de données…

Eléphant du PHP | 74 Messages

26 sept. 2008, 09:30

hello à tous,

Merci tout d'abord pour ce debat.

J'ai pas mal discuté avec mon client (car en effet il est statisticien et c'est lui qui souhaitait une structure en ligne avec peu de colonne), et on est arrivé à la meme conclusion que vous, t'en qu'on aura pas effectuer des tests de monté en charge pour une méthode puis l'autre on ne peux pas prendre de décision.

Ca devrai se faire d'ici une quinzaine de jours.

Je vous tiendrai au courant
Mon projet opensource de gestion de Devis, Commandes, Factures, pour TPE : OpenDCF : http://opendcf.1g6.biz

Eléphant du PHP | 422 Messages

26 sept. 2008, 09:54

C'est juste j'ai déjà lu des histoires comme ça, dont l'auteur nous assure que le fait d'avoir fait un schéma bizarre était complètement justifié. Sauf que j'attends toujours d'avoir un exemple concret.
Encore une fois, quand je vois quelqu'un qui arrive avec une table de 7 millions d'enregistrements et des centaines de champs, j'évite de donner quelque conseil que ce soit avant d'avoir étudié plus profondément le problème. Est-ce qu'il s'agit d'une base de données dans laquelle des modifications sont faites tous les jours -et en ce cas- on va privilégier une structure qui améliore les temps de réponse sur la saisie et la mise à jour des informations. Ou est-ce qu'il s'agit d'une base de données mise à jour une fois tous les x mois et utilisée en consultation, et dans ce cas, on va mettre en place des solutions de type datawarehouse dans lesquelles la dénormalisation, la redondance d'information et le fractionnement sont conseillés.
Et si les besoins sont mixtes, on peut même étudier une solution avec deux bases de données : une pour la saisie et la mise à jour et une pour la consultation avec un mécanisme de déversement automatique (ou pas), en temps réel (ou pas) de l'une dans l'autre. Et dans ce, il est fort probable que les structures des deux bases soient assez différentes.

D'ailleurs, à ce propos, vous ne trouvez pas que l'insertion d'un nouveau message dans le forum PHPFrance est de plus en plus long ? :roll:
Un statisticien n'est pas un informaticien, t'autant plus en bases de données
Justement. C'est pour ça qu'une structure avec une colonne par question est beaucoup plus facile à appréhender et que lui expliquer un and ou un or entre colonnes d'une table est plus aisé que faire des and ou des or sur des lignes différentes.
Exemple : avec une structure (id_repondant, id_question, valeur_reponse), comment fais-tu pour faire un comptage du nombre de répondants qui ont répondu 1 à la question 23 et 3 ou 5 à la question 12 ?

ViPHP
ViPHP | 5924 Messages

26 sept. 2008, 17:34

Un statisticien n'est pas un informaticien, t'autant plus en bases de données
Justement. C'est pour ça qu'une structure avec une colonne par question est beaucoup plus facile à appréhender et que lui expliquer un and ou un or entre colonnes d'une table est plus aisé que faire des and ou des or sur des lignes différentes.
Non, c'est pour cela qu'il faut un informaticien pour modéliser efficacement ce que lui représente d'une manière totalement inadaptée aux contraintes de la gestion de données.
Exemple : avec une structure (id_repondant, id_question, valeur_reponse), comment fais-tu pour faire un comptage du nombre de répondants qui ont répondu 1 à la question 23 et 3 ou 5 à la question 12 ?

Code : Tout sélectionner

SELECT COUNT(*) FROM reponses r1, reponses r2 WHERE (r1.id_repondant=r2.id_repondant) AND (r1.id_question=1 AND r1.valeur_reponse=23) AND (r2.id_question=12 AND r2.valeur_reponse IN(3,5));

Eléphant du PHP | 74 Messages

26 sept. 2008, 18:18

Exemple : avec une structure (id_repondant, id_question, valeur_reponse), comment fais-tu pour faire un comptage du nombre de répondants qui ont répondu 1 à la question 23 et 3 ou 5 à la question 12 ?

Code : Tout sélectionner

SELECT COUNT(*) FROM reponses r1, reponses r2 WHERE (r1.id_repondant=r2.id_repondant) AND (r1.id_question=1 AND r1.valeur_reponse=23) AND (r2.id_question=12 AND r2.valeur_reponse IN(3,5));
[/quote]

oui voila, on est arrivé au même résultat et c'est pour ce genre de truc que je suis pas vraiment chaud pour stocker en ligne plutot qu'en colonne.... (car un jour je sens bien que le client va avoir deux tables qualif et voudra tester plusieurs réponses sur chacune de ces tables ...)
Mais les benchs me diront quoi faire ...
Mon projet opensource de gestion de Devis, Commandes, Factures, pour TPE : OpenDCF : http://opendcf.1g6.biz

ViPHP
ViPHP | 5924 Messages

26 sept. 2008, 18:19

Sauf que cette structure est beaucoup plus stable, elle n'a que peu de chances de changer…

Et sinon, le bench, si tu n'as pas une quantité importante de données, et surtout des colonnes correctement indexées, il ne te servira à rien…

Eléphant du PHP | 74 Messages

26 sept. 2008, 19:58

Sauf que cette structure est beaucoup plus stable, elle n'a que peu de chances de changer…

Et sinon, le bench, si tu n'as pas une quantité importante de données, et surtout des colonnes correctement indexées, il ne te servira à rien…
en effet un des arguments des la structurte en ligne est qu'elle va moins bouger. Maid de manièrer régulière (environ tout les mois) la table est vider et entièrement recharger. A ce moment est ce genant avec une structure en colonne que le nombre de colonne change à chaque DROP + LOAD ?
Mon projet opensource de gestion de Devis, Commandes, Factures, pour TPE : OpenDCF : http://opendcf.1g6.biz