Je suis occupé à créer un système dans lequel je dois garder une trace de chaque changement du système. En d'autres termes, lorsqu'une colonne de la base de données est modifiée, j'ai besoin de savoir quel tableau, quelle colonne, lorsque le changement a été effectué, par quel utilisateur, de quelle valeur, à quelle valeur. P>
Ma première pensée était de créer une deuxième table pour chaque table à des fins de journalisation, contenant des champs tels que colonne_name, mises à jour_, mise à jour_on, de_value, to_value (en gardant les champs de_value et to_value comme chaînes de simplicité). Ceci, cependant, créera essentiellement un duplicata de la base de données. P>
Ma deuxième option serait de créer une table massive d'un type similaire (Table_Name, Nom de colonne, mise à jour_by, mise à jour_on, de_value, TO_Value) pour toutes les tables, mais cela entraînera une table ingérable, car les modifications se produiront fréquemment. . P>
Ces deux options ont le même problème, que je ne suis pas sûr comment référencer les colonnes d'une table et pire de tous, comment puis-je gérer une modification des noms de colonnes plus tard dans la durée de vie de l'application. P>
Toutes les pensées et suggestions seraient appréciées. P>
4 Réponses :
Ce serait un peu bizarre, mais vous pouvez ajouter une colonne "InsérezDontaMestamp" à chaque table en tant que clé primaire 2e. Ensuite, n'autorisez jamais les utilisateurs de mettre à jour les tables et de créer des vues qui ne montrent que l'enregistrement le plus récent.
Select * From Table
Inner Join (Select ID, Max(InsertedOnTimestamp) as LastestRecord From Table Group By ID) as Latest
On Table.ID = LatestID AND Table.InsertedOnTimestamp = Latest.LatestRecord
Ce n'est pas une mauvaise idée. Le problème est présent, cependant, lorsque vous avez une table avec 50 colonnes et que vous n'avez aucun changement dans l'une des colonnes. Cette méthode créerait inutilement une table massive avec des données en double.
Je viens de me rappeler que le terme pour ce type de fonctionnalité s'appelle "audit". Une recherche rapide de Google Recherche pour "La base de données Conception totale" a donné les liens intéressants suivants - pourrait valoir une lecture: p>
http://www.resfuldevelopment.net/david- Kawliche / Écriture / Time-après / P>
Meilleure mise en œuvre pour le modèle de données entièrement auditable? P >
http://www.sqlservercratral.com/articles/sql+ Puzzles / AnauditTrailGenerator / 2067 / P>
Ils étaient juste ceux qui m'ont démodé, vous pourriez trouver de meilleurs liens maintenant que vous connaissez le mot clé de "audit". p>
Merci pour les articles. J'ai regardé autour de moi et j'ai trouvé un peu plus, mais c'est dans le même sens que les réponses déjà fournies
L'information était utile mais j'ai toujours le problème dans ce que si je change le nom de la colonne d'une table, je n'aurai aucun moyen de savoir ce que c'était auparavant afin que je puisse effectuer des recherches (sauf si j'effectue une masse renommée de la masse dans la table d'histoire) . Cela signifie que je vais devoir garder un journal de change de noms de colonne. En ce qui concerne le besoin, je suis d'accord. C'est une "caractéristique très importante" qui est à peine utilisée. Le problème est que, lorsqu'il est nécessaire, il est généralement dû à une affaire de justice qui entraîne des mains en évolution de l'argent.
L'option XML n'est pas très bonne pour moi, car les modifications apportées aux tables devront être disponibles via un onglet, de sorte qu'à tout moment, tout utilisateur pourra voir qui a changé quoi.
Je vais faire des hypothèses ici: p>
Dans ce cas, la meilleure solution que je connaisse est de faire "Histoire" un concept de première classe dans votre conception. Le lien GREGL cité a une bonne description de cela; Ma mise en œuvre plus simple signifie fondamentalement avoir "valide_from" et "valide_until" et des colonnes "opérateur_id" sur chaque table et utiliser "is_valid" plutôt que l'opération de suppression. p>
Ceci est meilleur que l'audit des modifications apportées à des tableaux séparés, car il vous permet de créer une image complète de vos données à n'importe quel point de l'historique, avec toutes les relations entre les tableaux, en utilisant la même logique que votre code d'accès aux données régulières. . Cela signifie, à son tour, vous pouvez créer des rapports en utilisant des outils de rapport standard, répondre aux questions telles que "quel opérateur a changé les prix de tous les produits de la catégorie alimentaire", "Combien de produits étaient inférieurs à 100 $ le 1er janvier?" c. p>
Il consomme plus d'espace, et cela rend votre logique d'accès à la base de données plus complexe. Il ne joue pas non plus bien aux solutions ORM. p>
Cela a été une option favorite, mais cela ne convient pas exactement à mes besoins. Par exemple, sur un produit, je veux avoir un onglet dans lequel les utilisateurs peuvent voir une table avec toutes les modifications apportées à ce produit, quand et par qui. L'exemple dans le lien Au-dessus et Ici implique que je devrais faire une rangée par la comparaison de lignes afin d'énumérer un tableau de l'historique des changements
En effet - mais c'est (principalement) un problème pour l'interface utilisateur. Il n'est pas extrêmement difficile d'écrire une fonction de bibliothèque pour differez deux rangées, colonne par colonne; dépend bien sûr de votre code frontal. Dans ce modèle, vous montreriez un enregistrement pour chaque changement; Vous pouvez faire chaque colonne qui change entre rangées vertes. C'est beaucoup plus significatif (à mon avis) que "l'utilisateur x changé de prix de y à Z", car les changements ont tendance à entrer dans des groupes - en modifiant le prix et la description en même temps, par exemple.
Je suppose que cela pourrait fonctionner comme ça. J'allais avoir une série pour des lignes dans la table (à l'extrémité frontale) avec un grand nombre de "utilisateur x changé de prix de y à z", etc., etc. De plus, l'application aura près de 100 tables et je 'M. redire une deuxième table pour chacun. Et certaines tables ont près de 50 colonnes
Eh bien, je serais probablement stocker un identifiant d'objet de base de données au lieu d'une chaîne avec le nom de la colonne / table / etc., ce qui pourrait résoudre le problème de colonnes de renommage (si l'ID reste identique, pas sûr si cela le fait). Sinon, bonne question, j'ai toujours redouté avoir à faire quelque chose comme ça moi-même ...