Comment le contrôle de version d'un enregistrement dans une base de données
Disons que j'ai un enregistrement dans la base de données et à la fois administrateur et les utilisateurs normaux peuvent faire les mises à jour.
Quelqu'un peut-il suggérer une bonne approche/architecture de la façon de contrôle de version à chaque modification de ce tableau, il est donc possible d'annuler un enregistrement à une révision précédente.
Vous devez vous connecter pour publier un commentaire.
Disons que vous avez un
FOO
table que les administrateurs et les utilisateurs peuvent mettre à jour. La plupart du temps, vous pouvez écrire des requêtes sur la table FOO. Les jours heureux.Ensuite, je voudrais créer un
FOO_HISTORY
table. Cela a toutes les colonnes de laFOO
table. La clé primaire est le même que FOO plus un RevisionNumber colonne. Il y a une clé étrangère deFOO_HISTORY
àFOO
. Vous pouvez également ajouter des colonnes liées à la révision tels que le nom d'utilisateur et RevisionDate. Remplir le RevisionNumbers dans un nombre toujours croissant de la mode à travers tous les*_HISTORY
tables (c'est à dire à partir d'une séquence Oracle ou équivalent). Ne comptez pas sur il y a seulement un changement dans une seconde (c'est à dire ne pas mettreRevisionDate
dans la clé primaire).Maintenant, chaque fois que vous mettez à jour
FOO
, juste avant de vous faire la mise à jour vous insérez les anciennes valeurs dansFOO_HISTORY
. Vous faites cela à un certain niveau fondamental dans votre conception de sorte que les programmeurs ne peut pas accidentellement sauter cette étape.Si vous souhaitez supprimer une ligne de
FOO
, vous avez quelques choix. Soit en cascade et de supprimer toute l'histoire, ou d'effectuer une suppression logique par le repérage deFOO
comme supprimé.Cette solution est bonne lorsque vous êtes principalement intéressé par les valeurs actuelles et seulement de temps en temps dans l'histoire. Si vous avez toujours besoin de l'histoire, alors vous pouvez mettre effective de début et dates de fin et de conserver tous les enregistrements dans
FOO
lui-même. Chaque requête doit ensuite vérifier ces dates.There is a foreign key from FOO_HISTORY to FOO'
: mauvaise idée, je voudrais supprimer des enregistrements de foo sans changer l'histoire. la table d'historique devrait être d'insertion uniquement dans des conditions normales d'utilisation.Je pense que vous êtes à la recherche pour la gestion des versions le contenu des enregistrements de base de données (comme StackOverflow n'quand quelqu'un modifie une question/réponse). Un bon point de départ pourrait être à la recherche à un certain modèle de base de données qui utilise révision de suivi.
Le meilleur exemple qui me vient à l'esprit est de MediaWiki, le moteur de Wikipédia. Comparer le schéma de base de données ici, en particulier la la table de révision.
Selon quelles sont les technologies que vous utilisez, vous aurez à trouver une bonne diff/merge algorithmes.
Vérifier cette question si c'est pour .NET.
Dans la BI monde, vous pourriez faire cela par l'ajout d'une date de début et date de fin de la table que vous voulez version. Lorsque vous insérez le premier enregistrement dans la table, la date de début est rempli, mais la date de fin est nulle. Lorsque vous insérez le deuxième enregistrement, vous pouvez également mettre à jour la date de fin du premier enregistrement avec la date de début de l'enregistrement du second.
Lorsque vous souhaitez afficher l'enregistrement en cours, vous choisissez celui où la date de fin est nulle.
Cela est parfois appelé une de type 2 Lentement En Train De Changer De Dimension.
Voir aussi TupleVersioning
Mise à niveau vers SQL 2008.
Essayez d'utiliser SQL Suivi des modifications, dans SQL 2008. Au lieu de l'horodatage et la pierre tombale de la colonne de hacks, vous pouvez utiliser cette nouvelle fonctionnalité de suivi des modifications sur les données dans votre base de données.
MSDN SQL 2008 de Suivi des modifications
Voulais juste ajouter qu'une bonne solution à ce problème est d'utiliser un Temporelle de la base de données. De nombreux fournisseurs de bases de données offrent cette fonctionnalité, que ce soit hors de la boîte, ou via une extension. J'ai utilisé avec succès la temporelle de la table extension de PostgreSQL, mais d'autres l'ont aussi. Chaque fois que vous mettez à jour un enregistrement dans la base de données, la base de données tient à la version précédente de cet enregistrement.
Deux options:
Vous pouvez exécuter une vérification sur une table SQL via des déclencheurs SQL. À partir d'un déclencheur, vous pouvez accéder à 2 tables spéciales (inserted et deleted). Ces tables contiennent exactement les lignes qui ont été insérées ou supprimées à chaque fois que la table est mise à jour. Dans le trigger SQL, vous pouvez prendre ces lignes modifiées et les insérer dans la table d'audit. Cette approche signifie que votre audit est transparent pour le programmeur; et ne nécessitent aucun effort de leur part ou de toute implementational connaissances.
La prime ajoutée de cette approche est que la vérification se produire que si l'opération sql a eu lieu par l'intermédiaire de votre Dll d'accès aux données, ou par l'intermédiaire d'un manuel de requêtes SQL; (comme la vérification est effectuée sur le serveur lui-même).
Vous ne dites pas ce que la base de données, et je ne vois pas dans le post tags. Si c'est pour Oracle, je peux recommander l'approche qui est intégré dans le Concepteur: utilisation tables du journal. Si c'est pour une toute autre base de données, et bien, en gros, je recommande la même manière, trop...
La manière dont il fonctionne, dans le cas où vous souhaitez le reproduire dans une autre base de données, ou peut-être si vous voulez juste de comprendre, c'est que pour une table n'est plus que l'ombre de la table créée trop, juste normale table de base de données, avec le même champ de cahier des charges, en plus de certains champs supplémentaires: à l'instar de ce que l'action a été la dernière prise (chaîne des valeurs typiques "INS" pour les insérer, "UPD" pour mettre à jour et "SUPPR" pour supprimer), datetime lorsque l'action a eu lieu, et l'id utilisateur pour qui.
Par des déclencheurs, chaque action à une ligne dans la table insère une nouvelle ligne dans la table de revue avec les nouvelles valeurs, quelles mesures ont été prises, quand et par quel utilisateur. Vous n'avez pas jamais supprimer des lignes (au moins pas pour les quelques derniers mois). Oui, il va pousser de gros, facilement des millions de lignes, mais vous pouvez facilement le suivi de la valeur pour tout inscrits à n'importe quel point dans le temps depuis la journalisation commencé ou l'ancien journal rangées ai purgé dernier, et qui a fait la dernière modification.
Dans Oracle tout ce dont vous avez besoin est générée automatiquement en code SQL, tout ce que vous avez à faire est de compiler/exécuter, et il est livré avec un CRUD de base de l'application (en fait, seul "R") pour l'inspecter.
Je fais aussi la même chose. Je suis prise d'une base de données des plans de leçon. Ces plans doivent changement atomique gestion des versions de flexibilité. En d'autres termes, chaque changement, peu importe comment petit, les plans de leçon doit être autorisée, mais l'ancienne version doit être conservé intact ainsi. De cette façon, la leçon créateurs ont la possibilité de modifier les plans de leçon, tandis que les étudiants sont de les utiliser.
La façon dont il devrait fonctionner qu'une fois qu'un élève a fait une leçon, leurs résultats sont attachés à la version qu'ils ont réalisés. Si une modification est faite, leur résultat est toujours le point de leur version.
De cette façon, si une leçon critères est supprimé ou déplacé, leurs résultats ne changent pas.
La façon dont je suis en train de faire c'est par la manipulation de toutes les données dans une table. Normalement, j'aurais juste une id de champ, mais avec ce système, je suis à l'aide d'un identifiant et d'un sub_id. Le sub_id reste toujours avec la ligne, par le biais de mises à jour et suppressions. L'id est auto-incrémenté. Le plan de leçon logiciel lien vers le nouveau sub_id. Les résultats des élèves lien vers l'id. J'ai aussi inclus un horodatage de suivi lorsque des modifications qui s'est passé, mais il n'est pas nécessaire de gérer le versioning.
Une chose que je suis susceptible de changer, une fois que je l'ai testé, c'est que je peut utiliser le mentionné précédemment endDate nulle idée. Dans mon système, pour trouver la version la plus récente, je dois trouver le max(id). L'autre système semble juste pour endDate = null. Vous ne savez pas si les avantages outway avoir un autre champ de date.
Mes deux cents.
Tandis que @WW. la réponse est une bonne réponse à une autre façon est de faire une version de la colonne et de garder tous vos versions de la même table.
Pour une approche de table vous:
outer join
.Un exemple SQL de la
outer join
méthode à l'aide de numéros de révision est:La mauvaise nouvelle, c'est la-dessus nécessite une
outer join
et les jointures externes peut être lent. La bonne nouvelle est que la création de nouvelles entrées est théoriquement moins cher parce que vous pouvez le faire dans une opération d'écriture avec des transactions (en supposant que votre base de données est atomique).Un exemple de faire une nouvelle révision pour
'/stuff'
pourrait être:Nous insérer à l'aide des données anciennes. Ceci est particulièrement utile si par exemple vous souhaitez uniquement mettre à jour une colonne et d'éviter le verrouillage optimiste et ou des transactions.
Le drapeau de l'approche et la table d'historique approche nécessite deux de lignes à insérer/mettre à jour.
L'autre avantage avec le
outer join
numéro de révision approche est que vous pouvez toujours refactoriser aux multiples approche de table plus tard, avec le déclencheur, car votre déclencheur doit essentiellement à faire quelque chose comme ci-dessus.Alok suggéré
Audit table
ci-dessus, je voudrais l'expliquer dans mon post.J'ai adopté ce schéma, seule la conception de tableau sur mon projet.
Schéma:
Ce tableau peut contenir des dossiers historiques, pour chaque table, le tout dans un seul endroit, avec de compléter l'historique d'un objet dans un enregistrement. Cette table peut renseignée à l'aide de déclencheurs /crochets où des modifications de données, le stockage ancienne et la nouvelle valeur instantanée de la ligne cible.
Pros avec ce modèle:
Cons avec cette conception: