Modèles de version des données relationnelles dans une base de données MySQL?


12

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?


Notez que ce sont des bibliothèques pour cela. Par exemple, si vous utilisez Hibernate, il y a Hibernate Envers. Donc, si vous avez un framework gérant DAO pour vous, essayez de rechercher s'il y a quelque chose comme ça.
Walfrat

Réponses:


9

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

Alter table lists add revision_id integer;
Alter table list_tasks add revision_id integer;

Create Table revisions
{
   id int autoincrement... (revision id)
   list_id int...
   revdate datetime...
}

Lorsque l'utilisateur enregistre sa liste, créez une nouvelle révision dans le revisionstableau ci-dessus et affectez cette valeur aux éléments de la liste dans list_tasks, puis à l'ID de révision dans listspour 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 la listtable 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 liststableau. 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.


5

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:

AddUserID      int <whatever your system uses>
AddDateTime    datetime
UpdateUserID   int <whatever your system uses>
UpdateDateTime datetime
CurrentVersion int
IsDeleted      bit

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.


Je vote pour cela ainsi que pour GrandMasterB, les deux sont bons et celui à utiliser dépend de plus de détails sur les besoins spécifiques.
junky

-2

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.