Certains collègues et moi nous sommes lancés dans un débat sur la meilleure façon de stocker les données historiques. Actuellement, pour certains systèmes, j'utilise une table séparée pour stocker les données historiques et je garde une table originale pour l'enregistrement actif actuel. Alors, disons que j'ai la table FOO. Sous mon système, tous les enregistrements actifs iront dans FOO, et tous les enregistrements historiques iront dans FOO_Hist. De nombreux champs différents dans FOO peuvent être mis à jour par l'utilisateur, je veux donc garder un compte précis de tout mis à jour. FOO_Hist contient exactement les mêmes champs que FOO à l'exception d'un HIST_ID auto-incrémenté. Chaque FOO temps est mis à jour, j'effectue une déclaration d'insertion dans FOO_Hist similaire à: insert into FOO_HIST select * from FOO where id = @id
.
Mon collègue dit que c'est une mauvaise conception parce que je ne devrais pas avoir une copie exacte d'une table pour des raisons historiques et que je devrais simplement insérer un autre enregistrement dans la table active avec un indicateur indiquant que c'est à des fins historiques.
Existe-t-il une norme pour gérer le stockage des données historiques? Il me semble que je ne veux pas encombrer mes enregistrements actifs avec tous mes enregistrements historiques dans le même tableau, étant donné que cela peut être bien plus d'un million d'enregistrements (je pense à long terme).
Comment vous ou votre entreprise gérez-vous cela?
J'utilise MS SQL Server 2008, mais j'aimerais garder la réponse générique et arbitraire de tout SGBD.
la source
Je ne pense pas qu'il y ait une manière standard particulière de le faire, mais j'ai pensé que j'y ajouterais une méthode possible. Je travaille dans Oracle et notre cadre d'application Web interne qui utilise XML pour stocker les données d'application.
Nous utilisons quelque chose appelé un modèle Master - Detail qui, dans sa plus simple expression, consiste en:
Master Table par exemple appelée
Widgets
souvent contenant juste un ID. Contiendra souvent des données qui ne changeront pas avec le temps / qui ne sont pas historiques.Table de détail / historique par exemple appelée
Widget_Details
contenant au moins:Donc, essentiellement, une entité commence par avoir 1 ligne dans le maître et 1 ligne dans le détail. Le détail ayant une date de fin NULL et STATUS_CONTROL de 'C'. Lorsqu'une mise à jour se produit, la ligne actuelle est mise à jour pour avoir END_DATETIME de l'heure actuelle et status_control est défini sur NULL (ou «A» si vous préférez). Une nouvelle ligne est créée dans la table détaillée, toujours liée au même maître, avec status_control 'C', l'identifiant de la personne effectuant la mise à jour et les nouvelles données stockées dans la colonne XMLDATA.
C'est la base de notre modèle historique. La logique de création / mise à jour est gérée dans un package Oracle PL / SQL de sorte que vous transmettez simplement à la fonction l'ID actuel, votre ID utilisateur et les nouvelles données XML et en interne, il effectue toute la mise à jour / l'insertion de lignes pour représenter cela dans le modèle historique . Les heures de début et de fin indiquent quand cette ligne du tableau est active pendant.
Le stockage est bon marché, nous ne SUPPRIMONS généralement pas les données et préférons conserver une piste d'audit. Cela nous permet de voir à quoi ressemblaient nos données à un moment donné. En indexant status_control = 'C' ou en utilisant une vue, l'encombrement n'est pas exactement un problème. Évidemment, vos requêtes doivent prendre en compte que vous devez toujours utiliser la version actuelle (NULL end_datetime et status_control = 'C') d'un enregistrement.
la source
Je pense que votre approche est correcte. La table historique doit être une copie de la table principale sans index, assurez-vous que vous avez également l'horodatage de mise à jour dans la table.
Si vous essayez l'autre approche assez tôt, vous rencontrerez des problèmes:
la source
Dans SQL Server 2016 et versions ultérieures , il existe une nouvelle fonctionnalité appelée Tables temporelles qui vise à résoudre ce problème avec un effort minimal de la part du développeur . Le concept de table temporelle est similaire à Change Data Capture (CDC), à la différence que la table temporelle a résumé la plupart des choses que vous deviez faire manuellement si vous utilisiez CDC.
la source
Modifier la capture de données: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017
Il est pris en charge dans SQL Server 2008 R2, il peut avoir été pris en charge dans SQL Server 2008.
la source
cette question est assez ancienne mais les gens travaillent encore sur ce sujet. donc si vous utilisez oracle, vous pourriez être intéressé par Oracle Flashback: http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm
la source
Je voulais juste ajouter une option que j'ai commencé à utiliser parce que j'utilise Azure SQL et que la chose à plusieurs tables était beaucoup trop lourde pour moi. J'ai ajouté un déclencheur d'insertion / mise à jour / suppression sur ma table, puis j'ai converti le changement avant / après en json en utilisant la fonction "FOR JSON AUTO".
Cela renvoie une représentation JSON de l'enregistrement avant / après la modification. Je stocke ensuite ces valeurs dans une table d'historique avec un horodatage du moment où le changement s'est produit (je stocke également l'ID de l'enregistrement actuel concerné). À l'aide du processus de sérialisation, je peux contrôler la manière dont les données sont remplies en cas de modification du schéma.
J'ai appris cela à partir de ce lien ici
la source
Vous pouvez simplement partitionner les tables non?
«Stratégies de table partitionnée et d'index à l'aide de SQL Server 2008 Lorsqu'une table de base de données atteint des centaines de gigaoctets ou plus, il peut devenir plus difficile de charger de nouvelles données, de supprimer les anciennes données et de gérer les index. Juste la taille de la table rend ces opérations beaucoup plus longues. Même les données qui doivent être chargées ou supprimées peuvent être très importantes, ce qui rend les opérations INSERT et DELETE sur la table peu pratiques. Le logiciel de base de données Microsoft SQL Server 2008 fournit le partitionnement des tables pour rendre ces opérations plus faciles à gérer. "
la source
La vraie question est de savoir si vous devez utiliser les données historiques et les données actives ensemble pour le reporting? Si tel est le cas, conservez-les dans une table, partitionnez et créez une vue pour les enregistrements actifs à utiliser dans les requêtes actives. Si vous n'avez besoin de les regarder qu'occasionnellement (pour rechercher des problèmes légaux ou autres), mettez-les dans un tableau séparé.
la source
JOIN
créer deux tableaux dans quelques rapports historiques ou est-il plus difficile de modifier chaque insertion / mise à jour / suppression de tableau pour être conscient des problèmes historiques? En fait, un journal d'audit inclurait même les données actuelles dans la table d'historique, de sorte que la table actuelle ne devrait même pas être nécessaire dans un rapport.Une autre option consiste à archiver les données opérationnelles sur une base [quotidienne | horaire | peu importe]. La plupart des moteurs de base de données prennent en charge l'extraction des données dans une archive .
Fondamentalement, l'idée est de créer une tâche Windows ou CRON planifiée qui
De nombreux moteurs de base de données SQL sont fournis avec un outil qui peut être utilisé à cette fin. Par exemple, lors de l'utilisation de MySQL sous Linux, la commande suivante peut être utilisée dans un travail CRON pour planifier l'extraction:
la source
Je connais cet ancien article mais je voulais juste ajouter quelques points. La norme pour de tels problèmes est ce qui fonctionne le mieux pour la situation. comprendre la nécessité d'un tel stockage et l'utilisation potentielle des données historiques / d'audit / de suivi des modifications est très important.
Audit (objectif de sécurité) : utilisez une table commune pour toutes vos tables auditables. définir la structure pour stocker le nom de la colonne, avant la valeur et après les champs de valeur.
Archive / Historique : pour les cas tels que le suivi de l'adresse précédente, du numéro de téléphone, etc., la création d'une table séparée FOO_HIST est préférable si votre schéma de table de transactions actif ne change pas de manière significative à l'avenir (si votre table d'historique doit avoir la même structure). si vous prévoyez une normalisation de table, un changement de type de données, l'ajout / la suppression de colonnes, stockez vos données historiques au format xml. définir une table avec les colonnes suivantes (ID, Date, Version du schéma, XMLData). cela gérera facilement les changements de schéma. mais vous devez gérer xml et cela pourrait introduire un niveau de complication pour la récupération de données.
la source
Vous pouvez utiliser la fonction d'audit de serveur MSSQL. À partir de la version SQL Server 2012, vous trouverez cette fonctionnalité dans toutes les éditions:
http://technet.microsoft.com/en-us/library/cc280386.aspx
la source
Vous pouvez créer une vue matérialisée / indexée sur la table. En fonction de vos besoins, vous pouvez effectuer une mise à jour complète ou partielle des vues. Veuillez voir ceci pour créer mview et log. Comment créer des vues matérialisées dans SQL Server?
la source