Premier point : le TRIGGER ce sera un détail d'implémentation, qu'on choisisse de faire un update d'un nombre avec un TRIGGER ou manuellement depuis le code applicatif avec un UPDATE ça change rien. L'idée que tu évoques c'est du caching, pas du TRIGGER.
Pour insister sur ton exemple, n'oublions pas que sur JVC le nombre de posts qui s'affiche sur un topic est différent pour un utilisateur (qui voit le compte des messages visibles dans le topic) du compte qui s'affiche pour un admin (qui voit aussi les posts supprimés, probablement pour les modos aussi). Dans ce cas il y a un COUNT + un WHERE, donc effectivement faire le COUNT à chaque fois c'est pas une bonne stratégie, le WHERE empêche de profiter pleinement des index. Même si on avait pas cette contrainte, la stratégie n'est pas ouf car même si la table est indexée et qu'on fait un COUNT sans filtre,l'index lui-même n'est pas nécessairement bufferisé par l'engine.
Donc tu as mis le doigt dessus : le caching est généralement une bonne stratégie dès que possible. On évite de le généraliser car c'est une optimisation, et que comme on dit : "premature optimization is the root of all evil", ça complexifie pas mal de choses. Si tu n'as pas profilé ton appli pour prouver que le COUNT est un bottleneck, ne fais pas cette optimisation.
Pour le caching, plusieurs stratégies :
- rajouter des champs nb_posts_total et nb_posts_visibles (pour gérer les messages supprimés) sur la table topics, en les incrémentant/décrémentant ua besoin. Penser à gérer ça en transaction, comme tous les UPDATEs il y a un risque de race condition.
- créer une table séparée qui a la même fonction. ça évite de polluer la table "topics", c'est une bonne pratique
- gérer le cache ailleurs que dans ta BDD, dans un Redis par exemple. Ca alourdit la stack technique mais ça évite de s'emmerder avec les contraintes transactionnelles
Message édité le 01 avril 2017 à 22:54:57 par WatchItBurn