Populaire aujourd’hui, cette semaine, ce mois-ci – Modèle de conception

J’ai un système qui affiche les entrées classées par l’un des trois champs, le plus populaire Aujourd’hui, Cette semaine et Ce mois-ci. Chaque fois qu’une entrée est visualisée, le score est incrémenté de 1, ce qui change l’ordre.

Donc, si l’entrée 1 est nouvelle et consultée 10 fois aujourd’hui, ses scores seront:

Today: 10 Week: 10 Month: 10 

La solution actuelle

Pour le moment, j’ai simplement 3 champs associés à chaque entrée, un pour aujourd’hui, un pour cette semaine et un autre pour ce mois. Chaque fois qu’une entrée est visualisée, les trois scores sont incrémentés de 1.

À la fin de la journée, le score du jour est réinitialisé à 0. À la fin de la semaine en cours, le score de la semaine est défini sur 0 et à la fin du mois du calendrier en cours, le résultat du mois est défini sur 0.

Le problème

Bien que cela fonctionne et utilise peu d’espace, il n’est pas idéal pour deux raisons:

1) À la fin de la période en cours (jour, semaine, mois), cette valeur est réinitialisée à 0 en une seule fois, ce qui signifie qu’à 00:00:00 le classement est réinitialisé et que tous les scores quotidiens sont réglés sur 0. Il en va de même pour la fin de la semaine et la fin du mois. À 00:00:00 le 1er de chaque mois, tous les scores sont mis à 0, perdant toutes les données de classement existantes.

2) La fin du mois tombant généralement dans la semaine (du lundi au dimanche), les scores mensuels sont réinitialisés au cours de la semaine, les scores hebdomadaires étant supérieurs aux scores mensuels.

Solution possible

Je pourrais utiliser un compteur horaire glissant pour chaque heure du mois utilisé pour calculer les scores du jour, de la semaine et du mois actuels en fonction de l’indice des heures en cours.

 Array size = 31 * 24 = 744 int16 values 

Donc, le 1er à 4h du matin, la vue serait placée en heures [4]

 hours[4]++ 

La calculasortingce de statistiques utiliserait alors aujourd’hui la sum des 24 dernières valeurs et le score de cette semaine serait la sum des dernières (24 * 7) valeurs. Enfin, le mois en cours serait la sum des dernières valeurs (24 * 31).

Problèmes de solution

Le problème majeur avec la solution 1 est la configuration requirejse pour le disque / la mémoire. En utilisant 3 32 bits dans ma solution actuelle, je suis passé à 744 valeurs en 32 bits. Même si je les change en 16, je vais utiliser encore plus de mémoire par entrée

 Memory per Entry = 3 * 4 bytes = 12 bytes (Existing) Memory per Entry = 744 * 2 = 1,488 bytes (possible solution) 

Avec cette solution, mon utilisation de la mémoire par entrée a bondi de 12400% !!

Est-ce que n’importe qui peut suggérer une autre solution qui résoudrait les problèmes dans ma solution actuelle mais sans utiliser 1.5k par entrée?

Merci beaucoup!

Il s’agit en fait d’un problème courant: comment regrouper des données de manière efficace et conserver toutes les informations nécessaires.

Tout d’abord: avez-vous essayé de le faire à votre façon? Avez-vous vraiment manqué de stockage? Votre solution semble raisonnable.

Comment je le ferais

Je suppose que vous utilisez une firebase database pour conserver les données.

Je créerais deux tableaux distincts, un pour hourly statistiques hourly et un pour daily statistiques daily . Chaque article aurait exactement 24 lignes dans cette firebase database, une pour chaque heure. Cela serait utilisé pour hourly statistiques hourly . Pour mettre à jour une ligne spécifique, il vous suffit de connaître l’heure (0-23) et le paramètre entry_id. UPDATE count=count+1 WHERE hour=11 AND entry_id = 18164;

 entry_id foreign key | hour integer | count integer ---------------------+--------------+-------------- 1 | 0 | 123 1 | 2 | 1712 ... 

Les statistiques quotidiennes actuelles seraient soit calculées vers minuit (ou chaque fois que l’application en ferait le moins), soit additionnées à la demande. Dans les deux cas, une fois par jour, toutes les données horaires doivent être additionnées et insérées dans le tableau des statistiques daily .

 entry_id foreign key | day date | count integer ---------------------+------------+-------------- 1 | 2013-07-03 | 54197 1 | 2013-07-04 | 66123 ... 

Chaque entrée de plus de 31 (30/29/28) jours doit être supprimée. Ou non, si vous voulez des statistiques totales ou annuelles

Les avantages

  • vous conservez moins de données qu’avec des statistiques horaires complètes: 24 + 31
  • les sums sur la table horaire devraient être rapides, si indexées sur entry_id et hour
  • moins de mémoire utilisée que dans votre solution

Désavantages

  • script / déclencheurs / travaux supplémentaires nécessaires pour la mise à jour quotidienne des statistiques
  • plus de travail est nécessaire pour l’implémenter que dans votre solution

Une solution simple serait

 Use an array of 31. Today - the last value This Week score would be the sum of the last 7 values. This Month would be the sum of the last 31 values. At the end of each day, shift the whole array values by 1 to accommodate new value. 

En ce qui concerne votre commentaire,

 Use another array of size 24 to store hours visit count. Today - Sum of all elements of Array2 This Week score would be the sum of the last 7 values of Array1. This Month would be the Sum of all elements of Array1. At the end of each day, shift the whole array values of Array1 by 1 to accommodate new value. Last day visit count = Sum of all elements of Array2 

Peut-être qu’une sorte d’atténuation pourrait aider. Vous auriez besoin de 6 variables pour Today , Yesterday , cette ThisWeek , dernière LastWeek , ce ThisMonth , dernier LastMonth .

Ensuite, la note finale (par exemple quotidienne) peut être calculée comme suit: Today + Yesterday * attenuation( current_time - start_of_the_day ) .

Où l’atténuation est quelque chose comme 1 / (1 + k * time) , où k est ajustable en fonction de la rapidité avec laquelle vous voulez que votre classement des derniers jours se dégonfle.

MISE À JOUR: Envisager qu’une nouvelle entrée a été vue 123 fois au cours d’une journée. Et permet de mesurer le temps en secondes pour obtenir quelques chiffres. À 23:59, la note atsortingbuée à etrys serait 123 + 0 * 1 / (1 + k * 86340)^2 = 100 .

À minuit Today compteur devient Yesterday :

 0 + 123 * 1 / ( 1 + k * 0)^2 = 123 

Supposons qu’à midi une entrée gagne 89 vues supplémentaires.

 89 + 123 * 1 / ( 1 + k * 43200 )^2 = ? 

Eh bien, c’est le bon moment pour choisir le k . Si nous voulons que les anciennes vues disparaissent quatre fois en 12 heures, alors k est 1/43200 . Si nous voulons disparaître cent fois – 9/43200 . Dans ce cas:

 89 + 123 * 1 / ( 1 + 9 )^2 = 90.23 

Et ensuite à 23:59. Laissez l’entrée gagner 60 autres vues

 149 + 123 * 1 / ( 1 + (9/43200) * 86340 )^2 ~= 149.002 

Ainsi, les vues d’hier ont presque complètement perdu leur influence sur un classement en 24 heures. Bien sûr, vous pouvez jouer avec k ou la formule d’atténuation en général pour répondre au mieux à vos besoins. C’est juste un exemple.