I have a basic CRUD app with some hierarchical data, for example:
user --has many--> topic --has many--> post
I want to cache some statistics data, like number of posts in a topic, so it can be shown quickly to users. But I'd like to avoid querying the database and count all posts with the same topic id (I'm using mongodb, so no joins, but even if I use a relational database the problem is the same).
What is the typical pattern to resolve this problem in a web app?
Here's what I think:
Solution 1
Store number of child elements as a property of parent element. i.e. User.numOfTopics will store the number of topics, when a CRUD event happened, update parent element
if (new topic created) {
user = find user object from DB
++usr.numOfTopics;
}
Pros:
1). Simple to implement and understand
2). Accurate
Cons:
1). Every add/delete operation will not only update the affected element itself, but also its parent element, so I have twice as many database operations. If user add/delete a lot it may have a worse performance than counting numbers once.
2). Statistics gathering is coupled with normal business logic.
Solution 2
Build a in-process cache of statistics dynamically. Have a separate process calculating a user's statistics when a user connect, store the result in a cache and serve future request from there. Any future CRUD operations will update the in-process cache.
Pros:
1). Statistics gathering is separated from business logic (sort of)
2). Less DB query, which should mean better performance.
Cons:
1). Cached result is not persisted, so if the server reboots it has to rebuild the cache, which will give a long latency on first visit.
2). The statistics process runs in parallel with main process so the result is subject to race conditions.
Is there a better way to deal with this problem, I have searched SO for similar questions but most refer to specific frameworks like RoR and ASP.net. I'd like to know a general design pattern if there is one, or a solution works best for node.js.
Aucun commentaire:
Enregistrer un commentaire