J'essaie de trouver une approche pour un projet, où un utilisateur peut modifier des enregistrements et être en mesure de voir les versions antérieures de ces enregistrements. Voici un exemple de schéma simplifié, à l'aide d'une liste:
TABLE list (
id int auto_increment primary key,
user_id int,
title varchar(255)
);
TABLE list_tasks (
id int auto_increment primary key,
list_id int,
title varchar(255),
order int,
is_complete tinyint
);
Ainsi, un utilisateur peut entrer et apporter plusieurs modifications à la liste (c.-à-d. Ajouter ou supprimer des tâches, réorganiser des tâches, marquer certaines comme terminées, renommer certaines, etc.), puis les enregistrer. À ce stade, j'aimerais générer une «version 2» de la liste et des tâches, et leur permettre de visualiser les versions précédentes, mais lorsqu'ils accèdent à la liste, obtenez toujours la dernière version.
Existe-t-il un modèle d'approche / de conception commun pour gérer les données de version de cette manière dans une base de données MySQL?
la source
Réponses:
C'est assez courant de vouloir le faire dans un db. Bien que vous y apportiez une touche, vous souhaitez suivre une révision d'une liste d'éléments.
Une façon de le faire pourrait être de modifier la structure telle que
Lorsque l'utilisateur enregistre sa liste, créez une nouvelle révision dans le
revisions
tableau ci-dessus et affectez cette valeur aux éléments de la liste danslist_tasks
, puis à l'ID de révision danslists
pour marquer cet ID comme révision «actuelle». Lorsque l'utilisateur modifie les éléments, ne modifiez pas les éléments existants - insérez-en plutôt de nouveaux avec un nouvel identifiant de révision et mettez à jour lalist
table avec cette révision pour la marquer comme celle en cours.Ensuite, pour répertorier les éléments actuels, répertoriez les éléments de l'ID de révision actuel spécifié dans le
lists
tableau. Pour parcourir les versions précédentes, vous pouvez obtenir une liste des révisions précédentes des listes à partir du tableau des révisions, puis répertorier les éléments individuels en fonction de cet identifiant.la source
Cette solution utilise une table d'audit distincte. Il a des avantages et des inconvénients. Vous pouvez préférer éliminer les anciens enregistrements de votre table principale. L'amélioration des performances peut être négligeable.
Ajoutez les champs suivants à chaque table auditée:
Vous devrez mettre à jour ces champs chaque fois que les données changent. CurrentVersion est incrémenté de 1 (il pourrait être utilisé comme moyen de verrouiller un enregistrement, mais c'est une autre question.) IsDeleted fournit une "suppression logicielle" afin qu'il puisse être référencé à l'avenir.
Tables d'audit distinctes Chaque table doit avoir une version _Archive ou _History correspondante de la table. Ceux-ci n'ont probablement pas besoin d'être indexés de la même manière. Évidemment, un seul champ de clé primaire ne s'appliquera pas. Vous devriez pouvoir créer une clé composite à partir du champ ID et de UpdateDateTime.
À l'aide d'un déclencheur (cela traitera des modifications apportées à l'intérieur ou à l'extérieur de votre code. Vous pouvez décider si cela fonctionne pour votre situation.) Ou d'un autre codage, lorsqu'un enregistrement est ajouté, mis à jour ou supprimé, une copie de l'enregistrement est placée dans l'archive / table d'historique. Toutes les versions et autres champs d'audit sont conservés. Cela vous dira ce que les utilisateurs ont fait et quand. Le tableau peut être comparé à lui-même pour voir quand un enregistrement a été modifié ou pour voir les tendances.
J'ai bien vu ce travail au cours des dernières années. J'aimerais entendre des inconvénients que je ne considère peut-être pas.
la source
Je vous suggère de lire cet article bien détaillé.
https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850
Une autre approche consiste à avoir une colonne version_id dans votre table et un indicateur «actuel» qui spécifie quelle ligne est la ligne actuelle. Chaque fois que vous avez besoin d'une mise à jour, vous pouvez insérer une nouvelle ligne et définir l'indicateur «actuel» de la version existante sur 0 / faux et la ligne nouvellement ajoutée sur 1.
De cette façon, vous pouvez créer une vue affichant uniquement celles avec le jeu d'indicateurs actuel.
la source