Comment stocker un historique de manière optimale ?

Comment stocker un historique de manière optimale ? - SQL/NoSQL - Programmation

Marsh Posté le 01-03-2006 à 19:00:32    

Bonjour,
 
Je voudrais savoir quelle est la manière optimale de stocker des changements apportés à des enregistrements dans une base de données relationnelles, de facon à gaspiller le moins de place possible et à retrouver rapidement l'historique d'un objet.
 
Pour simplifier, j'ai une table produit avec les champs suivants:
 

id - titre - code - auteur - prix - date_modif - date_sortie


 
Ces données sont amenées à être changées, et je voudrais conserver un historique complet des modifications.
 
Mon souci se situe au niveau de la facon dont stocker ces modifications.
 
Etant débutant en SGDB ( à part le select, les vues et quelques trucs, je ne connais pas grand chose), j'ai pour le moment ceci comme solution :
 
table historique avec les champs:
 

id - id_produit (clé étrangère sur produit.id) - date_modif -champ_modif - old_value - new value


 
Par exemple si le produit d'id 5 est passé de 40€ à 50€ le 01/01/2005, j'aurai :
 

x - 5 - 01/01/2005 - prix - 40 - 50


 
si l'auteur change de toto à tata  le 02/02/2002 j'aurai :
 

x - 5 - 02/02/2002 - auteur - toto -tata


 
Est-ce que vous voyez une autre solution ?
 
merci

Message cité 2 fois
Message édité par ory le 01-03-2006 à 19:09:57
Reply

Marsh Posté le 01-03-2006 à 19:00:32   

Reply

Marsh Posté le 01-03-2006 à 19:19:07    

ory a écrit :

Bonjour,
 
Je voudrais savoir quelle est la manière optimale de stocker des changements apportés à des enregistrements dans une base de données relationnelles, de facon à gaspiller le moins de place possible et à retrouver rapidement l'historique d'un objet.
 
Pour simplifier, j'ai une table produit avec les champs suivants:
 

id - titre - code - auteur - prix - date_modif - date_sortie


 
Ces données sont amenées à être changées, et je voudrais conserver un historique complet des modifications.
 
Mon souci se situe au niveau de la facon dont stocker ces modifications.
 
Etant débutant en SGDB ( à part le select, les vues et quelques trucs, je ne connais pas grand chose), j'ai pour le moment ceci comme solution :
 
table historique avec les champs:
 

id - id_produit (clé étrangère sur produit.id) - date_modif -champ_modif - old_value - new value


 
Par exemple si le produit d'id 5 est passé de 40€ à 50€ le 01/01/2005, j'aurai :
 

x - 5 - 01/01/2005 - prix - 40 - 50


 
si l'auteur change de toto à tata  le 02/02/2002 j'aurai :
 

x - 5 - 02/02/2002 - auteur - toto -tata


 
Est-ce que vous voyez une autre solution ?
 
merci


 
Les pb de cette façon de faire, c'est que
1) les valeurs "old" et "new" sont différentes d'une ligne à l'autre (nombre pour "40" et "50", texte pour "toto" et "tata" )
2) tu auras des requêtes de folie pour visualiser l'état de ta bdd à une date 't' du passé
 
Autre façon plus gourmande en espace mais moins gourmande en requêtes, créer une copie historique de ta table "produit" en y intégrant tous les champs + la date du changement.
Sinon tu peux intégrer la date du changement dans ta table "produit". Chaque changement insère un nouvel enregistrement et quand tu veux la valeur réelle du produit, tu n'affiches que le dernier enregistrement...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-03-2006 à 20:27:53    

salut
C'est un problème difficile qui n'a pas de réponse unique. Il faut plus d'éléments fonctionnels pour pouvoir abroder réellement le sujet dans ton cas précis
volumes ?
durée de conservation ?
dans quels buts ?

Reply

Marsh Posté le 01-03-2006 à 21:39:30    

tiens, une question qui m'intéresse bien aussi.
instantdha rma > juste pour l'info, que faire dans les cas suivants :  
1) gros volumes et durée de conservation limitée, le temps de vérifier les nouvelles infos, et restaurer la base en cas d'anomalie
2) gros volume et durée de conservation illimitée, dans le but de savoir qui a fait quoi, pas forcément restaurer la base

Reply

Marsh Posté le 02-03-2006 à 17:57:33    

instantdharma a écrit :

salut
C'est un problème difficile qui n'a pas de réponse unique. Il faut plus d'éléments fonctionnels pour pouvoir abroder réellement le sujet dans ton cas précis
volumes ?
durée de conservation ?
dans quels buts ?


 
volumes: environ 20 000 entrées, auxquelles s'ajoutent une dizaine d'entrées chaque semaine
durée de conservation: pour le moment c'est quasi illimité, mais je vais voir pour imposer une certaine limite ( 3 ans, a priori)
dans quels buts ? pour simplifier, au niveau comptable il me faut déjà ces données (-1an = stock, +1an = immobilisations), et le reste pour des rotations entre différents points de vente selon le succès commercial, et aussi pour des statistiques à long terme.
 
 

Reply

Marsh Posté le 04-03-2006 à 11:46:03    

d'autres idées ?

Reply

Marsh Posté le 04-03-2006 à 12:04:09    

ory a écrit :


table historique avec les champs:
 

id - id_produit (clé étrangère sur produit.id) - date_modif -champ_modif - old_value - new value


 
Par exemple si le produit d'id 5 est passé de 40€ à 50€ le 01/01/2005, j'aurai :
 

x - 5 - 01/01/2005 - prix - 40 - 50


 
si l'auteur change de toto à tata  le 02/02/2002 j'aurai :
 

x - 5 - 02/02/2002 - auteur - toto -tata


 
Est-ce que vous voyez une autre solution ?


 
Ta solution est totalement inexploitable en terme de requete et elle comporte des relations qu'il est impossible de normaliser dans un rdbms. C'est donc à proscrire.
 
Sans redondance, ta table produit ressemble à ça, c'est lent mais ça prend pas de place

id - titre - code - date_sortie


 
Ta table historique contient les champs modifiables et ressemble à ça :

id - id_produit - date_modif - auteur - prix


(bon, id n'est pas très utile, ça depend du modele)
 
Autre méthode : tu gardes ta table produit telle qu'elle est, tu construis une table historique comme celle du produit qui va servir de "sauvegarde" à chaque modif d'un produit. Tu fais une copie dans la table historique à chaque modif. Très rapide (la table produit contient toujours la derniere version) mais très consommateur de place. A toi de voir.

Reply

Marsh Posté le 04-03-2006 à 13:54:59    

smaragdus a écrit :

Ta solution est totalement inexploitable en terme de requete et elle comporte des relations qu'il est impossible de normaliser dans un rdbms. C'est donc à proscrire.
 
Sans redondance, ta table produit ressemble à ça, c'est lent mais ça prend pas de place

id - titre - code - date_sortie


 
Ta table historique contient les champs modifiables et ressemble à ça :

id - id_produit - date_modif - auteur - prix


(bon, id n'est pas très utile, ça depend du modele)
 
Autre méthode : tu gardes ta table produit telle qu'elle est, tu construis une table historique comme celle du produit qui va servir de "sauvegarde" à chaque modif d'un produit. Tu fais une copie dans la table historique à chaque modif. Très rapide (la table produit contient toujours la derniere version) mais très consommateur de place. A toi de voir.


 
merci  :jap:  
 
Donc pas de solution idéale, tout est question de compromis alors

Reply

Marsh Posté le 10-03-2006 à 16:03:49    

moi je vote pour la solution bourrin comme les autres :
- seconde table de même structure, avec "datupd" en plus
- pas de PK, juste des index non uniques
- un bon gros trigger des familles sur la table pour allimenter automatiquement la table d'historisation

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed