Comment autoriser le versionnage des entrées de la base de données (données)?
Pensez aux capacités des systèmes de gestion de contenu pour annuler les modifications d'articles.
Quels sont leurs avantages/inconvénients?
Il existe essentiellement deux approches: une table d'audit, avec toutes les valeurs précédentes stockées, ou inclure une date de début/fin dans le tableau, et toutes les mises à jour créent un nouvel enregistrement tout en fermant l'ancien.
Mise à jour: SQL SERVER 2016 prend en charge cela en tant que modèle de conception/type de table - https://docs.Microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server -2017
Une idée consiste à utiliser des "bases de données à insertion seule". L'idée de base est que vous ne supprimez ou ne mettez jamais à jour les données sur une ligne .
Chaque table qui doit être suivie aura deux colonnes datetime
from
et to
. Ils commencent par la valeur NULL
dans chacun (du début à la fin du temps). Lorsque vous devez "modifier" la ligne, vous ajoutez une nouvelle ligne et, en même temps, vous mettez à jour le to
de la ligne précédente en Now
et le from
dans le ligne que vous ajoutez à Now
.
Pour plus d'informations, consultez:
Cette technique est appelée AuditTrail
pour gérer les données héritées, et sa mémoire stocke un peu l'historique des modifications.
Il semble qu'une question de cette nature soit déjà publiée:
Je pense que vous pouvez utiliser des déclencheurs pour chaque table et maintenir les données dans _history (ou vous pouvez donner n'importe quel nom) et à chaque insertion, la mise à jour, la suppression sur la table principale déclenchera votre déclencheur et vous pouvez enregistrer les détails dans cette table. est également disponible avec la base de données SQLite si vous en utilisez une.
Ce mécanisme est également utile pour les grands projets. Dans ce tableau, vous pouvez enregistrer les informations de l'utilisateur qui a effectué les modifications ainsi que l'horodatage des modifications. vous pouvez ensuite restaurer votre table selon l’horodatage correspondant à vos besoins.
Chaque base de données a sa propre façon d'écrire et de coder les déclencheurs. Si vous utilisez SQLite, visitez SQLite.org pour la syntaxe. Pour d'autres bases de données, vous pouvez visiter leurs sites officiels.
Vous connaissez probablement le moteur Sqlite db. L'ensemble de la base de données est enregistré dans un seul fichier. L'API prend également en charge les systèmes de fichiers virtuels, vous pouvez donc organiser le stockage n'importe où et avec n'importe quel format, il suffit de répondre aux opérations de lecture et d'écriture à des décalages de fichiers particuliers. Les applications possibles peuvent être le cryptage, la compression, etc. La meilleure partie est que la couche conteneur ne devrait rien savoir des bases de données, du format de fichier sql ou sqlite, obéissez simplement aux rappels xRead et xWrite.
L'une des idées était de mettre en œuvre la fonction de machine à remonter le temps. Ainsi, toute opération xWrite enregistre chaque segment qu'elle écraserait dans l'historique "Annuler" et l'utilisateur peut choisir une date dans le passé pour voir ce que la base de données contenait (probablement en mode lecture seule). Je n'ai pas encore d'exemple de travail (il y avait un discussion à ce sujet dans la liste de diffusion sqlite), mais probablement d'autres moteurs fournissent des API VFS donc quelque chose de similaire est possible. Et une fois implémenté, il devrait être compatible avec les structures de bases de données de toute complexité.
La méthode que nous utilisons pour le contrôle de version des entrées de la base de données consiste à utiliser une table d'audit. Le tableau a un schéma dans le sens de:
Seq - Int ' Unique identifier for this table
Event - Char ' Insert / Update / Delete
TblName - Char ' Table that had field value changed
FldName - Char ' Field that was changed
KeyValue - Char ' delimited list of values for fields that make up the PK of table changed
UsrId - Char ' User who made the change
OldValue - Char ' Old value (converted to character)
NewValue - Char ' New value (converted to character)
AddTs - DateTime ' When the change was made
Nous avons ensuite des déclencheurs sur Insert/Update/Delete des tables que nous voulons suivre.
Avantages:
Les inconvénients:
J'en fais une version maintenant. pour chaque enregistrement, j'ai une date insérée, une date modifiée et un indicateur booléen d'enregistrement actif. Pour l'insertion initiale, les dates d'insertion et de modification sont toutes deux définies sur Now () (cet exemple se trouve dans Access) et l'indicateur d'enregistrement actif est défini sur true
. puis si je modifie cet enregistrement, je copie le tout dans un nouvel enregistrement, en changeant le (s) champ (s) que l'utilisateur modifie, je laisse la date d'insertion égale à l'original et je change la date de modification en Now (). Je retourne ensuite l'indicateur d'enregistrement actif de l'enregistrement d'origine vers false
et le nouvel enregistrement vers true
. J'ai également un champ pour ModifiedRecordsParentID où je sauvegarde l'identité de l'enregistrement d'origine.
Si je dois même interroger, je peux simplement renvoyer des enregistrements où ActiveRecord = true
et je ne recevrai que les informations les plus récentes.
aussi, si vous souhaitez stocker TOUTES les modifications apportées à la base de données au fil du temps, vous souhaiterez peut-être vérifier la journalisation ( https://stackoverflow.com/questions/3394132/where-can-i-find-the-mysql -transaction-log )