J'essaie de développer un petit outil de reporting (avec backend sqlite). Je peux le mieux décrire cet outil comme un grand livre de "transactions". Ce que j'essaie de faire, c'est de garder une trace des «transactions» de l'extrait de données hebdomadaire:
- "nouveau" (ou ajouter) - la ressource est nouvelle pour mon application car mon application n'a peut-être pas suivi cette ressource auparavant car elle n'a pas été vue via des extraits.
- "mise à jour" (ou hit) - il y a eu une utilisation récente de cette ressource, mise à jour de la période de rétention d'une semaine.
- "supprimer" (ou supprimer) - cet élément n'a vu aucune utilité depuis le dernier rapport (facultatif, mais il serait bien d'avoir pour représenter graphiquement les changements d'une semaine à l'autre de la demande de ressources).
Tout ce que j'ai, c'est un extrait de données hebdomadaire (fichier plat délimité par des tuyaux) provenant d'un ancien système d'archivage / gestion des enregistrements sur lequel je n'ai aucun contrôle.
Chaque ligne peut être distillée à la base:
resource_id | resource info | customer_id | customer_info
Exemples de données:
10| Title X | 1 | Bob
11| Another title | 1 | Bob
10| Title X | 2 | Alice
L'objectif est de faciliter la génération de rapports sur les ressources qui n'ont pas été utilisées pendant X mois (en fonction du dernier hit). Il y a une période de rétention où les ressources sont conservées pour en faciliter l'accès si elles sont populaires. Une ressource qui n'a pas été utilisée depuis 18 mois est marquée pour un archivage à long terme ailleurs.
Ce doit être un problème courant. Vous vous demandez s'il existe un algorithme à usage général pour déterminer ce qui est nouveau / identique / supprimé entre les ensembles de données (db vs dernier extrait)?
Si vous conservez de toute façon les mises à jour dans un backend SQLite, vous pouvez transformer la mise à jour hebdomadaire en une nouvelle table et la comparer aux données archivées avec des requêtes, avant de la fusionner.
Exemple d'utilisation de SQL pour rechercher de nouveaux ajouts à une table: /programming/2077807/sql-query-to-return-differences-between-two-tables
Si un champ de votre base de données stocke la date de la transaction, vous pouvez simplement interroger tous les utilisateurs qui ont effectué des transactions au cours des 18 derniers mois. L'archive n'est alors que la base de données complète. Alternativement, vous pouvez interroger tous les utilisateurs qui ne l'ont pas fait, extraire leurs données, puis les supprimer. Les mises à jour correspondent à toutes les lignes horodatées cette semaine.
la source
Vector
.Idée alternative:
Analysez votre liste de transactions dans une sorte de structure de données, comme un tableau. (En C ++, pensez
Vector
, et en Java,.ArrayList
)Effectuer une requête sur votre backend SQL telles que
SELECT DISTINCT customer_id FROM Transactions ORDER BY customer_id
et emballez les ID client triés distincts en un ensemble,old
. Si vous faites exactement la même chose avec uneWHERE
clause séparant les anciennes et les nouvelles transactions, vous pouvez ignorer l'étape 3.Obtenez les ID client uniques des nouvelles mises à jour dans une structure de données distincte, dans l'ordre trié. Il y a deux structures de données que vous pouvez utiliser pour obtenir est dans une structure de données,
new
. Le tri par insertion dans une liste à double liaison est très simple, mais l'utilisation d'une table de hachage intermédiaire s'exécuterait en un temps presque linéaire, ou si vous triez le tableau d'origine de toute façon, il est facile d'en obtenir un ensemble.Faites la différence
new
- enold
utilisant la bibliothèque standard de votre langue préférée. Votre langue préférée a cet algorithme dans sa bibliothèque standard?Les autres choses que vous voulez faire sont définitivement des requêtes SQL après avoir mis à jour votre base de données de transactions.
Remarque à l'étape 3: tenez compte de la nature de vos données. Supposons que votre fichier texte répertorie les commandes par ordre chronologique, et au cours d'une semaine typique, il y a beaucoup de nouveaux clients qui reçoivent un nouveau
customer_id
par ordre croissant. Supposons que la plupart des autres commandes proviennent d'un petit nombre de clients fidèles fidèles, avec moinscustomer_id
. Ensuite, vos entrées sont déjà principalement triées. Dans ce cas, un tri par insertion où vous essayez d'insérer bascustomer_id
aucustomer_id
début d'une liste à double lien et haut à l'arrière fonctionnerait bien dans la pratique.la source
Si je comprends bien de votre question, vous avez réellement resource_id (+ info) et "list" de client (id + info).
Ainsi, vous pouvez facilement conserver la liste des clients par ressource et vérifier le dernier nœud de chaque liste de la ressource (afin de connaître l'heure de la dernière opération; il vous suffit d'ajouter un champ de date à votre client dans le code)
Je ne suis pas familier avec SQL, donc je donne mon exemple avec
HashMap
et List mais je suis sûr que c'est la même idée:,HashMap <Resource, List<Customer>>
quandResource
devrait contenir resourceID comme clé etCustomer
devrait contenir l'ID client, les informations et la date d'opération.Avec cette idée, vous pouvez facilement connaître la dernière heure de fonctionnement et modifier n'importe quelle ressource (ajouter \ supprimer une ressource \ client).
la source
Si vous utilisez une base de données SqLite, si vous ajoutez également la date du lot en tant que colonne du tableau,
il serait assez facile d'utiliser un SQL pour obtenir les ressources non utilisées au cours des X derniers jours
Je n'ai pas testé le SQL mais ça devrait vous donner une idée
la source
D'après le message d'origine, il semble que les données en cours d'ingestion n'ont pas de champ pour indiquer la date / heure de la transaction, et je suppose que le fichier est ingéré fréquemment selon un calendrier tel que quotidien, horaire, etc.
Je gérerais cela en ajoutant une colonne d'horodatage SQL qui est soit générée automatiquement au niveau de la base de données, soit par le code qui extrait les données et les insère dans la base de données. Ensuite, vous mettez un index sur cette colonne d'horodatage et vous en avez terminé. Laissez le moteur DB faire le travail pour le rendre efficace pour répondre à la question "combien de transactions ne se sont pas produites depuis cette époque", ou "combien entre cette heure et cette heure".
Ensuite, vous planifiez un travail pour interroger et calculer les écarts sur lesquels vous souhaitez générer un rapport. Les transactions qui sont "nouvelles" sont des transactions qui n'ont aucun enregistrement dans la base de données avant la date à laquelle vous demandez "nouveau depuis". Les anciens enregistrements sont ceux qui n'ont effectué aucune transaction depuis une date limite.
la source
N'est-ce pas à cela que servent les HashTables? Si tout ce que vous voulez faire est de garder une trace des ressources qui ont été utilisées au cours des derniers mois et de supprimer les ressources qui n'ont pas été consultées au cours des 18 derniers mois, vous pouvez utiliser un HashTable où la clé est le resource_id et la valeur est le dernière date d'accès.
Pour archiver les enregistrements> 18 mois, vous pouvez parcourir tous les enregistrements de la table de hachage et simplement supprimer (ou déplacer) ces enregistrements spécifiques. (vous pouvez le faire chaque semaine lorsque le rapport arrive)
la source