Conseils sur systèmes d'historique des modifications

Conseils sur systèmes d'historique des modifications - SQL/NoSQL - Programmation

Marsh Posté le 04-07-2012 à 12:44:29    

Bonjour,
 
j'ai fait quelques recherches sur le forum mais sans trouver vraiment ce que je cherche.
 
Je suis plutôt débutant avec Oracle et les architectures DB complexes et j'aurais besoins de conseils pour mon système d'historisation des modifications.
 
Dans premier temps, j'avais pensé ajouté une ligne dans la même table lors de la modification d'une ligne.
J'aurais donc :
1. je récupère les infos de la ligne avant modification
2. j'ajoute une ligne avec ces infos et référence à la ligne qui va être modifiée
3. je modifie la ligne
 
Par exemple, pour une table RELATION :
id (PK)
type_relation
date_creation
(date_modification)
id_self (FK -> référence à une id de cette même table pour l'hitorique | peut être null, pour la ligne "active", non historisée)
 
Ce système fonctionne pas mal, il suffit de rechercher les lignes où "id_self" est null pour avoir les lignes actives.
 
Mais du coup je perd les avantages de contraintes uniques : quand j'ai plusieurs champs, si un champ devrait être unique et qu'on ne le modifie pas mais qu'on modifie d'autres champs la valeur va être identique dans la ligne active et historisée. Je ne peux donc pas rendre ce champ unique.
 
Une bonne solution semble de passer par des tables historiques.
Mais dans mon cas j'ai déjà +/- 60 tables et ce n'est qu'un début => est-ce une solution de faire une table histo pour chacune des tables ?
 
Le but de l'historique : le responsable veut garder l'historique de toutes les modifications apportées à toutes les données de toutes les tables !  
Et il veut y avoir accès depuis une application (dans la partie admin) que nous développons (en PHP).
 
La durée : a priori illimitée.
 
Le volume ; peu élevé au bébut mais va très vite augmenter puisque le responsable veut intégrer l'ensemble de la gestion de son entreprise dans cette DB (de l'encodage d'un client au process de fabrication).
 
Voilà, c'est peut-être un peu brouillon.. dites-moi et je préciserai.
 
Seb


Message édité par beobes le 04-07-2012 à 12:44:57
Reply

Marsh Posté le 04-07-2012 à 12:44:29   

Reply

Marsh Posté le 04-07-2012 à 17:45:22    

Malheureux! :/ Tu auras beaucoup plus intérêt de centraliser ça,  
Maintiens une seule table Log centrale dans laquelle tu renseignes au minimum : la table concernée, la date de modification et l'objet de la modification
 
Comment gères-tu l'historisation des lignes ? Si ce n'est pas déjà fait tu peux passer assez simplement par des Triggers : http://www.aide-oracle.net/2009/09/les-triggers.html


---------------
À défaut des dragons il me reste les moulins
Reply

Marsh Posté le 05-07-2012 à 11:02:19    


Merci pour le retour !
 
Je passe effectivement par des triggers pour l'historisation des lignes.
Enfin... j'étais en train de les mettre en place et je me suis dit qu'un réflexion plus approfondie s'imposait avant de le faire pour ma 70aine de table...
 
Le "problème" que je vois avec la table log, c'est que pour certaines modifications, il faudrait y avoir un accès rapide.
Par exemple, la relation d'un individu avec une entreprise ; il faut que l'on puisse avoir accès à cette infos rapidement.
Il me semble que ce sera plus long d'aller chercher dans la table log.
 
Dans la "solution" où on stocke dans la même table avec une référence à la ligne active pour les lignes d'historique, on peut récupérer toutes les relations d'un individu et voir directement les changements d'états.
Mais il y a un "problème" de redondance quand on ne modifie qu'un champ sur x champs et que toute la ligne est copié...
 
Je ne suis pas vraiment familiarisé avec cette table log...
Comment est-ce qu'on stocke "l'objet de la modification" dans cette table ?
 
Est-ce que je ne pourrais pas envisager d'avoir :
- des tables historiques pour les tables les plus importantes dont on veut avoir un accès facile et rapide à l'historique
- l'historisation des lignes avec référence à la ligne active dans la même table pour certaines tables
- un table log pour les tables dont on veut juste pouvoir suivre les erreurs éventuelles ?
 
Enfin dernière question (j'abuse un peu...), quel est l'impact sur les performances d'avoir un très grand nombre de tables et une DB très lourde en terme d'espace disque (au-delà de la complexité des requêtes) ?
 
 
 
 

Reply

Marsh Posté le 05-07-2012 à 11:06:48    

+1 pour une seule table. Tu devrais aussi avoir un niveau d'intérêt du log pour filtrer les MAJ pas importantes des MAJ importantes. Pense aussi aux logs qui concernent un objet supprimé.
 
Tu peux regarder le système de log que j'ai fait pour mon outil de help-desk ASTRES (cf ma signature). Dans /Astres/Common/, regardes les 2 fichiers DbLogEventsLibrary.php et FctLibrary.php (la fonction logEvent() ). Et dans Config.php, tu verras le système paramétrable que j'ai prévu (entre autre, un log rotatif). Après, suivant le niveau de log dont tu as besoin, tu peux améliorer le système que je propose ;) Perso, je m'en sers aussi pour alimenter des flux RSS de l'application...
 
Edit :

Code :
  1. --
  2. -- Structure de la table `LogEvents`
  3. --
  4.  
  5. CREATE TABLE `LogEvents` (
  6.  `LogEventID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  7.  `LogEventDate` datetime NOT NULL,
  8.  `LogEventItemID` int(10) UNSIGNED NOT NULL,
  9.  `LogEventItemType` varchar(30) NOT NULL,
  10.  `LogEventService` varchar(30) NOT NULL,
  11.  `LogEventAction` varchar(30) NOT NULL,
  12.  `LogEventLevel` tinyint(3) UNSIGNED NOT NULL DEFAULT '5',
  13.  `LogEventTitle` varchar(255) DEFAULT NULL,
  14.  `LogEventDescription` mediumtext,
  15.  `LogEventLinkedObjectID` int(10) UNSIGNED DEFAULT NULL,
  16.  `SupportMemberID` smallint(5) UNSIGNED NOT NULL,
  17.  PRIMARY KEY  (`LogEventID`),
  18.  KEY `SupportMemberID` (`SupportMemberID`),
  19.  KEY `LogEventItemID` (`LogEventItemID`)
  20. ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COMMENT='Table which contains logged events.';


Message édité par rufo le 05-07-2012 à 11:11:02

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 05-07-2012 à 11:12:36    

beobes a écrit :


Merci pour le retour !
 
Je passe effectivement par des triggers pour l'historisation des lignes.
Enfin... j'étais en train de les mettre en place et je me suis dit qu'un réflexion plus approfondie s'imposait avant de le faire pour ma 70aine de table...
 
Le "problème" que je vois avec la table log, c'est que pour certaines modifications, il faudrait y avoir un accès rapide.
Par exemple, la relation d'un individu avec une entreprise ; il faut que l'on puisse avoir accès à cette infos rapidement.
Il me semble que ce sera plus long d'aller chercher dans la table log.
 
Dans la "solution" où on stocke dans la même table avec une référence à la ligne active pour les lignes d'historique, on peut récupérer toutes les relations d'un individu et voir directement les changements d'états.
Mais il y a un "problème" de redondance quand on ne modifie qu'un champ sur x champs et que toute la ligne est copié...
 
Je ne suis pas vraiment familiarisé avec cette table log...
Comment est-ce qu'on stocke "l'objet de la modification" dans cette table ?
 
Est-ce que je ne pourrais pas envisager d'avoir :
- des tables historiques pour les tables les plus importantes dont on veut avoir un accès facile et rapide à l'historique
- l'historisation des lignes avec référence à la ligne active dans la même table pour certaines tables
- un table log pour les tables dont on veut juste pouvoir suivre les erreurs éventuelles ?
 
Enfin dernière question (j'abuse un peu...), quel est l'impact sur les performances d'avoir un très grand nombre de tables et une DB très lourde en terme d'espace disque (au-delà de la complexité des requêtes) ?


 
Cf mon post précédent pour le principe de base du système de log. Ensuite, si t'as besoin de tracer le changement de valeur de chaque champ d'une table, tu peux très bien rajouter à la structure de la table de log un champ de type blob contenant, en XML par ex, les valeurs des champs avant la MAJ.
Comme ça, avec les logs successifs, t'es capable de retrouver l'état d'un enregistrement d'une table à une date donnée et comparer avec les valeurs courantes de la table concernée.
 
Edit : voir mon post sur un sujet similaire : http://forum.hardware.fr/hfr/Progr [...] m#t2093324


Message édité par rufo le 05-07-2012 à 11:14:06

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 05-07-2012 à 11:37:33    


Merci rufo !
 
Je vais voir tout ça de plus près.
Ca me semble déjà très intéressant (en tout cas pour certaines données) !

Reply

Marsh Posté le 05-07-2012 à 11:55:58    

Pour info, moi, c'est sous Mysql que mon appli tourne. Mais le principe peut être mie en oeuvre sous Oracle. Comme j'utilise pas les triggers, c'est mon appli PHP qui gère ce qui est logué.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 05-07-2012 à 16:40:26    

beobes a écrit :


Le "problème" que je vois avec la table log, c'est que pour certaines modifications, il faudrait y avoir un accès rapide.
Par exemple, la relation d'un individu avec une entreprise ; il faut que l'on puisse avoir accès à cette infos rapidement.
Il me semble que ce sera plus long d'aller chercher dans la table log.


 
Tant qu'elle est indexée tu ne rencontreras pas de soucis de rapidité. Oublie sincèrement l'idée d'utiliser plusieurs tables, ce sera très difficilement maintenable - imagine juste les manipulations à réaliser en cas de modification de structure ou d'ajout/suppression de table.  
Idem pour la duplication des lignes, tu vas surcharger tes tables de base alors qu'elles sont réservées au stockage et non à l'historisation.
 
"Objet de la modification" c'est à votre libre arbitre pour décrire ce qui a été changé :) Ca dépend ce que veut lire le boss.


---------------
À défaut des dragons il me reste les moulins
Reply

Marsh Posté le 05-07-2012 à 17:26:08    

+1 pour une seule table. En plus, c'est plus facile à requêter si on cherche des maj concernant plusieurs tables.
 
Si la table est trop grosse et que ça gêne côté perfs, y'a toujours la solution de partitionner (en lignes ou colonnes, ici, plutôt en ligne sur le champ correspondant à la date de maj) ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 09-07-2012 à 11:28:56    


Merci à tous !
 
Je vais donc aller vers l'idée d'une table qui reprend toutes les modifications et enlever la duplication de ligne dans la même table.
 
Ce ceci dit, j'envisage tout de même de faire plusieurs tables (mais peu !) de log/historique. Je pourrai ainsi historiser des tables de "même type" ensemble.
(Par exemple : pour certaines tables, on devra accèder +/- souvent - et rapidement - à l'historique des changement, pour d'autres pas.)

Reply

Marsh Posté le 09-07-2012 à 11:28:56   

Reply

Marsh Posté le 09-07-2012 à 11:44:36    

Je vais me répéter mais honnêtement ne te focalise pas sur la conception par rapport pour un soucis de rapidité dans ce cas ci. A moins que tes tables demandent une historisation avec une structure totalement propre à elles, pourquoi pas.
Juste pour exemple, je travaille actuellement sur une table de 9 millions de lignes et je sors des résultats en 0,6 secondes en passant simplement par un index!


---------------
À défaut des dragons il me reste les moulins
Reply

Marsh Posté le 09-07-2012 à 11:55:23    

A nouveau +100000 pour 1 seule table. Comme dit dans mon précédent, post, pour les éventuels pbs de perfs, partitionnement de la table, index, tuning du serveur sql...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Sujets relatifs:

Leave a Replay

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