Comment suivre une chose dans le temps (MYSQL)

  • Auteur de la discussion Auteur de la discussion FortTrafic
  • Date de début Date de début
WRInaute passionné
Bonjour, c'est la première fois que j'essaye de faire une chose comme ça, donc je me demande quelle est la façon de faire que les pros utilisent déjà.

Ce que je veux faire c'est suivre l'évolution des propriétés d'une entitée quelconque au fil du temps.

Prenons un exemple concret :

On a un catalogue produits, chaque produit a un nom, une description, un prix, et d'autres propriétés.

J'aimerai donc faire un programme qui suive l'évolution des propriétés de chaque produit. Sans jamais toucher au catalogue bien sûr. Simplement en vérifiant chaque jour chaque produit pour voir si une des propriétés à changé, et si oui, en garder une trace. C'est à dire ne rien perdre des modifications. Exemple :

Un jour, un produit change de prix, un autre a son nom modifié :
- je veux garder en mémoire dans une base mysql, l'ancien prix, et le nouveau prix, avec la date du changement du prix. Pareil pour le nom de l'autre produit.


Donc, en ayant des milliers de produits, comment faire pour ne pas avoir une base de données qui grossissent trop vite?
Si à chaque fois qu'il y a un changement, j'enregistre une nouvelle entrée avec toutes les propriétés du produit, la taille de la base de données risque de vite grimper...

Comment est-ce que les pros gèrent ce problème? Est-ce qu'il font une table par propriété par exemple, avec une table produit réduite au minimum (id produit) au lieu d'une table pour les produits avec chaque propriété dans des champs?

J'espère vraiment m'être fait comprendre et que vous pourrez m'aider, m'indiquer des resources ou me donner des pistes, car je sais que ce n'est pas facile d'aider avec seulement de la théorie, sans exemple réel.

Merci.
 
WRInaute accro
Je ferais simple : une table avec id_produit, identifiant de la propriété, valeur avant modif et date de modif. Et j'ajouterais une liaison avec la table des utilisateurs, de manière à savoir qui a fait la modification.
 
WRInaute passionné
Merci mais il n'y a pas d'utilisateurs. Ce n'est pas pour suivre qui fait quoi. Mais simplement pour suivre les modifications des propriétés des produits dans le temps.
J'irai consulter chaque produit une fois par jour (par exemple) et si il a changé depuis le dernier enregistrement de changement, je veux enregistrer la date et ce qui a changé. Mais sans perdre bien sûr ce que j'avais déjà enregistré à son sujet dans le passé.

Ce que tu me proposes marche quand même?

Tu dis faire une table disons CHANGEMENTS :
id_produit, id_propriete, nouvelle_valeur, date_changement


C'est ça? (je n'ai pas besoin de l'ancienne valeur puisqu'elle sera déjà dans la table, même id_produit et id_propriete mais a une date precedente, non?)

Donc, en faisant comme ca, je devrais commencer la vie de mon programme par remplir la table changements pour chaque produit et chaque proprietes avec la date de départ.

C'est bien ça? Est-ce que tu l'as déjà fait en vrai? Ca fonctionne bien? Mais du coup tout est concentré sur cette table, cela ne va-t'il pas faire exploser le nombre d'entrées assez rapidement?
 
WRInaute passionné
En fait je ne pense pas que je veux suivre toutes les propriétés, style les changements de nom ou de description, ce n'est pas important..
Ca serait plutôt pour suivre le prix, le nombre de ventes, des choses comme ça..

Je me demande s'il ne faudrait pas que j'ai une structure dans le style :
Table produit avec les champs pour toutes les proprietes
Table propriete qui contiendra 2 ou 3 proprietes que je veux suivre
Table produit_propriete pour faire le lien entre les deux premieres tables

Et donc ca serait cette derniere table qui contiendrait toutes les modifications donc j'aurai comme champ :
Table produit_propriete
produit_id
propriete_id
value
date

Et quand je detecte un changement d'une des proprietes que je veux suivre, je l'enregistre dans cette table, et ensuite je met a jour l'entrée complete dans la table produit.

Est-ce que ca vous parait ok?
 
WRInaute accro
En fait, l'idéal pour ce genre de choses, c'est une table produit avec les propriétés qui ne changent jamais, et une table avec les propriétés qui changent, et et id_produit, type_propriete, date_debut, date_fin, la date_fin étant automatiquement mise à jour quand on créé une nouvel enregistrement pour id_produit + type_propriete avec date_debut > select max de date_debut pour id_produit and type_de_propriete (désolée pour le jargon mais tu vois l'idée)

Tu n'as que deux tables, et la structure est clean, avec les champs permanents et les champs variables
 
WRInaute passionné
Merci, j'avoue je n'ai pas compris, je vais essayer de le re-écrire pour être sûr :

Table Produit


Table Propriete
id_produit
type_propriete
valeur
date_debut
date_fin

quand on a une propriete qui change pour un produit on UPDATE la dernière entrée pour ce couple id_produit/type_propriété pour changer la date_fin et ensuite on INSERT une nouvelle entrée pour ce couple en renseignant la date_debut (= à la date_fin de l'ancienne entrée)

C'est ça?
Donc pourquoi tu as une date_fin dans cette table puisque en principe la date_fin c'est la date_debut du plus recent enregistrement, faut-il vraiment avoir cette date dans deux entrées différentes?
Est-ce que ca sert ensuite pour faciliter les requetes ? Quand je voudrais afficher des graphiques montrant les changements dans le temps?

Et donc il n'y a pas besoin d'avoir 3 tables? Une table pour les produits, une pour les proprietes variables et une pour faire la liaison entre les deux? Ta deuxieme table fait donc office de table propriete variable et de laison? C'est sans doute mieux oui en fait, un peu moins compliqué pour les requetes.

Et, donc tu penses que c'est bon comme ça? La table proprietes va grossir assez vite je pense.. C'est vrai que ca ne sert à rien de s'inquiéter maintenant, j'ai le temps de voir venir..

Allez je vais essayer comme ça, merci beaucoup.
 
WRInaute accro
Oui c'est ça.
La date de fin (qui devrait être un timestamp, d'ailleurs, au cas où tu changes deux fois dans la journée) est effectivement là pour faciliter les requêtes. ça te permet par exemple d'avoir la valeur actuelle avec un simple select sur une valeur vide, au lieu d'un max sur les dates de début. C'est aussi une sorte d'instinct que c'est mieux avec que sans...

En mettant tous les champs de la table propriété (sauf sans doute la valeur elle même), même si elle est grosse, tu auras amha une meilleure performance qu'avec un join sur trois tables.
 
WRInaute accro
FortTrafic a dit:
quand on a une propriete qui change pour un produit on UPDATE la dernière entrée pour ce couple id_produit/type_propriété pour changer la date_fin et ensuite on INSERT une nouvelle entrée pour ce couple en renseignant la date_debut (= à la date_fin de l'ancienne entrée)
Mode j'essaye de suivre ce qui se raconte : en fait tu fait un record par produit/propriété par valeur constatée sur un intervalle de temps.
 
WRInaute accro
zeb a dit:
Mode j'essaye de suivre ce qui se raconte : en fait tu fait un record par produit/propriété par valeur constatée sur un intervalle de temps.
Voilou ^^

Et l'avantage de stocker l'intervalle sur chaque enregistrement, c'est que c'est nettement plus simple si on veut suivre, par exemple, la fréquence des changements.
 
WRInaute accro
ok pour les deux tables mais il en faudra bien une 3°, la table des propriétés, pour faire le lien entre id_propriété et le nom de la propriété. Sinon pour éditer des tableaux statistiques ça ne sera pas pratique de parler uniquement d'id de propriété sans jamais les nommer.

Moi par simple soucis de ne pas mélanger les éléments qui servent à des besoins statistiques et les éléments courants, je mettrais toutes les propriétés d'un article dans la base article et il y aurait une seconde table id_article/id_propriété qui aurait pour données :
- nouvelle valeur
- date début
- date fin

Cette table serait mise à jour en même temps qu'on met à jour la table des articles plutôt que d'aller scruter toute la base tous les jours pour détecter les changements (en plus, quand il y a plusieurs changements dans la journée c'est pas possible de les tracer de cette façon).
 
Nouveau WRInaute
Bonjour,

C'est très simple ce que tu veux faire ... Si les prix changent très souvent, tu seras obligés d'avoir une grosse table, mais tu n'es pas obligé d'utiliser MySQL, le NoSQL peut être une solution. Si tu as un disque SSD, tu peux stocker dans des fichiers également... et laisser MySQL dodo :-).

Sinon pour MySQL, c'est un jeu d'enfant : chaque fois que tu changes de prix, tu ajoutes ancien dans une table "anciens_prix" avec le id, la date et prix, à ce jour.... :-)
id (auto increment)
id_produit (index) ne dois pas être unique
prix
date_de_modif

Ext...
 
WRInaute accro
L'idée d'un fichier est très bonne comme ces infos ne servent qu'au traçage et ne seront certainement pas utilisées en affichage.
A chaque modification de propriété, écrire un enregistrement dans un fichier de type CSV avec les champs séparés par des ";"
Liste des champs à écrire :
id_produit
n° propriété
nouvelle valeur
date changement
heure changement

Et le jour où tu veux faire tes stats tu télécharges le fichier et tu l'ouvres dans Excel. Tu peux même y écrire à chaque ligne le libellé du produit et le nom de la propriété. Ca va faire plus lourd mais ça sera plus facilement manipulable sous excel
 
WRInaute passionné
Merci tout le monde, écoutez je vais faire une pause sur le topic car je m'aperçois que ça fait trop à digérer, il y a même des parties de vos messages que je n'arrive pas à comprendre, à m'imaginer mentalement ce que vous voulez dire. Je pense que c'est un manque d'expérience qui fait ça, c'est frustrant, même en lisant doucement et plusieurs fois, ya rien à faire :-)

Donc je vais commencer le travail, je vais avancer, et je pense d'ici quelques jours maximum je serai bien dans le bain et je reviendrai sur le topic je pense que tout sera plus clair à ce moment là, et s'il faut que je retourne en arrière et refasse la structure de la base de données, je le referrai.

Sinon juste pour préciser, indigène, en fait ces infos je vais m'en servir pour afficher pour chaque produit son historique, donc oui ces logs doivent pouvoir me servir en programmation à tout moment.

Par contre l'idée par exemple de faire un champ historique_prix et dedans écrire par exemple :
timestamp#XY;timestamp#XYZ;timestamp#XX;etc.
C'est pas mal je trouve, ca sera simple d'afficher l'histoirique et la dernière valeur, en plus des autres infos sur le produit.

Par contre si je veux faire d'autres affichages, par exemple lister les produits par ordre de nombre de changements (activité) ca ne sera pas possible avec mysql directement/simplement, à moins de faire un champ de plus, un compteur_prix, que j'incrémenterai à chaque modification du prix.

Bref, peut être que je pourrais faire ça avec une seule table..

Pas sur que ce soit bien, si il faut prévoir des champs supplémentaires pour chaque affichage que je veux faire.. :-)

Bref, j'arrête de parler tout seul, je vais m'y mettre pour de bon et reviendrai sur cette discussion quand j'aurai avancé.

Merci à tous en tous cas pour vos propositions, j'aimerai bien pouvoir en discuter plus mais je sens que je suis trop limité par le manque d'expérience là dedans :-)
 
WRInaute accro
pas besoin d'un compteur prix, tu peux le faire avec une simple requete sql et un GROUP BY

Exemple :
Code:
SELECT DISTINCT(a.id_produit) as produit, COUNT(a.id_produit) as cpt FROM TBL_stats a GROUP BY a.id_produit order by cpt DESC, id_produit ASC LIMIT 20";
qui va te donner la liste des produits les plus modifiés

En ajoutant une clause where tu aura la liste des produits le plus souvent modifiés sur une propriété particulière
 
WRInaute accro
indigene a dit:
dans un fichier de type CSV...
Super pas pratique pour faire une simple courbe qui est destinée a s'afficher dans une page web. en local pour un usage perso pourquoi pas mais bon un CSV prend autant sinon plus de place qu'un fichier de base de données qui est en lui même un fylesystème un poil plus évolué qu'XL ...

Les fichiers disque c'est bien mais quand on les compare a une base faut prendre un peu de recul. En effet une base de données stocke aussi ses datas sur le disque mais c'est un système optimisé destiné a trier, ranger dans des meilleurs conditions. De plus les fonctions d'une base sont généralement mieux écrites que celle d'un simple tableur qui a de plus besoin de l'OS de façon importante (en comparaison) pour tourner. Accessoirement une multitude de fichiers prennent plus de place sur le disque que les même datas rangées dans une base, cela tiens a la technologie utilisée qui fait que les fichiers ne sont pas forcement contigus, qu'ils comprennent forcement des vides (liés a la taille de l'unité minimum du disque) et que donc en comparaison la base qui range tout au même endroit dans un unique "fichier" (comprendre espace disque) sera forcement plus rapide car elle économise énormément de temps d'accès (déplacement des têtes de lecture du disque qui prennent un temps énorme en comparaison de la vitesse de traitement des datas)

L'utilisation des fichiers pourrait se justifier si par exemple on envisageais d'en créer un par produit ... car là on gagnerait en gestion certainement d'autre avantages (on pourrait par exemple y ranger autre chose que les simples variations de prix et des dates), mais faudrait penser alors que l'espace disque est un facteur négligeable car là ça serait la fête du slip en terme de perte de place pure ...
 
WRInaute accro
Mais quand le directeur demande une stat précise sur une point précis, tu vas donner la base sql à la secrétaire ou à l'assistante ?

Il faut faire du développement, attendre plusieurs jours, prendre des risques avec des modifications en prod

Le fichier CSV qui contient toutes les infos facilement manipulables par n'importe quelle secrétaire peut être partagé facilement. En quelques heures le directeur a son document et peut le présenter dans une réunion en l'intégrant à un powerpoint. Il est libre d'en extraire les informations qu'il veut sans passer par une lourde phase de développement web.
 
WRInaute passionné
Oui bien sûr mais là le directeur c'est moi, la secrétaire aussi :-)

Sinon dans d'autres circonstances je suis d'accord avec toi.
 
WRInaute accro
indigene a dit:
Mais quand le directeur demande une stat précise sur une point précis, tu vas donner la base sql à la secrétaire ou à l'assistante ?
j'en ai eu 12000 des cas comme ça, ça prend 30s a créer tu leur fait un script d'export personnalisé en CSV et c'est réglé ... un clic et le tonton qui comprend rien au sql a son fichier Xl de ***** sur son windwos :D
T'as besoin de 4 lignes php ... un header CSV, une requête et une itération avec un echo c'est pas franchement compliqué.

Si on part la dessus ton fichier Xl au bout de 80000 produit ça va ramer la mort a l'ouverture ... Je pense qu'il faut être logique dans l'énoncé on parle de produits et de suivi journalier ou plus bref de "big data" pas de notepad ...

Je suis a la base même pas certains qu'une techno Sql sur du disque dur classique soit adapté pour ça ... En fait, en toute rigueur, faudrait avoir une idée du volume de produit à gérer et de la fréquence de surveillance / changement avant de décider du comment ...

je te dis ça car j'ai justement bossé sur un truc de suivi de produits de grande conso et quand on commence a initialiser la table produit ça cause déjà sévère dans le poste. Alors ajoute a ça un simple suivi journalier des prix chez une dizaine de fournisseurs ou plus et ça deviens mortel.
 
Discussions similaires
Haut