Existe-t-il des directives ou des règles empiriques permettant de déterminer quand stocker les valeurs agrégées et quand les calculer à la volée?
Par exemple, supposons que j'ai des widgets que les utilisateurs peuvent évaluer (voir le schéma ci-dessous). Chaque fois que j'affiche un widget, je peux calculer la note moyenne des utilisateurs à partir du Ratings
tableau. Sinon, je pourrais stocker la note moyenne sur la Widget
table. Cela m'éviterait de devoir calculer la note chaque fois que j'afficherai le widget, mais je devrais alors recalculer la note moyenne chaque fois qu'un utilisateur évaluait un widget.
Ratings Widgets
--------- -------
widget_id widget_id
user_id name
rating avg_rating <--- The column in question
À quelle fréquence devez-vous calculer / afficher les valeurs par rapport à la fréquence de modification / mise à jour des nombres sous-jacents?
Ainsi, si vous avez un site Web avec 10 000 hits quotidiens affichant une valeur qui ne changera qu'une fois par heure, je le calculerais lorsque les valeurs sous-jacentes changeraient (pourrait être un déclencheur de base de données, par exemple).
Si vous avez un outil pour consulter les statistiques, où les statistiques changent à la seconde, mais que trois personnes seulement ont accès, et qu'elles ne le consultent que quelques fois par jour, je serais plus susceptible de calculer à la volée. (à moins que cela ne prenne quelques minutes à calculer qu'avoir des données obsolètes en premier lieu n'est pas grave ... et mon patron me dit de générer simplement le problème à partir de cron toutes les heures, pour qu'il n'ait pas attendre quand il veut le regarder.)
la source
Utilisez la table StaleWidgets en tant que file d'attente de widgets "non valides" (à recalculer). Utilisez une autre tâche (asynchrone) pouvant recalculer ces valeurs. La période ou le moment du recalcul dépend de la configuration système requise:
la source
Je suggérerais de calculer à la volée si le calcul n'est pas trop lourd et dans le cas où vous avez une calcul complexe et des mises à jour fréquentes mais pas cette fréquence de lecture que vous pouvez stocker des données calculées et avoir une colonne supplémentaire (bool) qui stockera si un recalcul est requis ou non. . Par exemple, définissez cette colonne sur true chaque fois qu'un recalcul doit être effectué, mais ne le recalculez pas et définissez cette colonne sur false (cela représentera la dernière valeur calculée et non obsolète).
De cette façon, vous ne devez pas recalculer à chaque fois, vous calculerez uniquement lorsque vous devez lire et recalculer la valeur de la colonne est vraie. De cette façon, vous économiserez beaucoup de recalcul.
la source
Pour le cas en particulier, il existe une solution différente selon laquelle il n'est pas nécessaire d'ajouter toutes les cotes et de la diviser par le total pour obtenir la moyenne. Au lieu de cela, vous pouvez avoir un autre champ contenant le total des avis. Ainsi, chaque fois que vous ajoutez un classement, vous calculez la nouvelle moyenne à l'aide de (avg_rating × total + new_rating) / total, ce qui est beaucoup plus rapide que l'agrégat et réduit les lectures de disque ne pas avoir à accéder à toutes les valeurs d'évaluation. Des solutions similaires pourraient s'appliquer à d'autres cas.
L'inconvénient est que ce n'est pas une transaction acide, vous pouvez donc vous retrouver avec une notation obsolète. Mais vous pouvez toujours résoudre ce problème en utilisant des déclencheurs dans la base de données. L'autre problème est que la base de données n'est plus normalisée, mais n'ayez pas peur de dénormaliser les données en échange de performances.
la source