Question

J'ai besoin de stocker toutes les versions d'une entité d'une manière facilement indexée et je me demandais si quelqu'un a des commentaires sur ce système à utiliser.

Sans versioning le système est tout simplement une base de données relationnelle avec une ligne par, par exemple, personne. Si l'état de la personne change cette ligne est modifiée en conséquence. Avec l'entrée versioning devrait être mis à jour dans une telle manière que nous pouvons toujours revenir à une version précédente. Si je pouvais utiliser une base de données temporelle ce serait libre et je serais en mesure de demander «quel est l'état de toutes les personnes que d'hier à 14 heures vivant à Dublin et âgé de 30 ans. Malheureusement, il ne semble pas y avoir de projets open source matures qui peuvent faire le temps.

Une façon vraiment méchant de le faire est tout simplement d'insérer une nouvelle ligne par changement d'état. Cela conduit à la duplication, en tant que personne peut avoir de nombreux domaines, mais un seul changement par la mise à jour. Il est alors également assez lent pour sélectionner la version correcte pour chaque personne donnée un horodatage.

En théorie, il devrait être possible d'utiliser une base de données relationnelle et d'un système de contrôle de version pour simuler une base de données temporelle, mais cela semble assez horrible.

Alors je me demandais si quelqu'un a rencontré quelque chose de semblable avant et comment ils ont approché?

Mise à jour Comme suggéré par Aaron ici la requête que nous utilisons actuellement (dans une base MySQL). Il est sans aucun doute lent sur notre table avec> 200k lignes. (Id = clé de table, person_id = id par personne, en double si la personne a de nombreuses révisions)

  

SELECT nom d'une personne où p = p.id (sélectionner max (id) d'une personne où person_id = p.person_id et l'horodatage <=: timestamp)

Mise à jour Il semble que la meilleure façon de le faire est avec une db temporelle, mais étant donné qu'il n'y a pas de ceux open source là la meilleure méthode consiste à stocker une nouvelle ligne par la mise à jour. Le seul problème est la duplication des colonnes inchangées et une requête lente.

Était-ce utile?

La solution

Il y a deux façons d'aborder ce sujet. Les deux supposent que vous insérez toujours de nouvelles lignes. Dans tous les cas, vous devez insérer un horodatage (created) qui vous indique quand une ligne a été « modifiée ».

La première approche utilise un certain nombre de compter le nombre de cas, vous avez déjà. La clé primaire est la clé de l'objet ainsi que le numéro de version. Le problème avec cette approche semble être que vous aurez besoin d'un select max(version) pour faire une modification. En pratique, cela est rarement un problème puisque pour toutes les mises à jour de l'application, vous devez d'abord charger la version actuelle de la personne, le modifier (et incrémenter la version), puis insérer la nouvelle ligne. Donc, le vrai problème est que cette conception le rend difficile à exécuter des mises à jour dans la base de données (par exemple, attribuer une propriété à de nombreux utilisateurs).

La prochaine approche utilise des liens dans la base de données. Au lieu d'une clé composite, vous donnez chaque objet une nouvelle clé et vous avez un champ replacedBy qui contient la clé de la prochaine version. Cette approche permet de trouver facilement la version actuelle (... where replacedBy is NULL). Les mises à jour sont un problème, cependant, puisque vous devez insérer une nouvelle ligne et mettre à jour un.

Pour résoudre ce problème, vous pouvez ajouter un pointeur arrière (previousVersion). De cette façon, vous pouvez insérer les nouvelles lignes, puis utilisez le pointeur de retour pour mettre à jour la version précédente.

Autres conseils

Voici une enquête sur (un peu daté) la littérature sur les bases de données temporelles: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

Je recommande de passer un bon moment assis avec ces références et / ou Google Scholar pour essayer de trouver quelques bonnes techniques qui correspondent à votre modèle de données. Bonne chance!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top