我使用Postgres
作为主数据库,使用REDIS进行缓存。我正在研究一个db查询的缓存机制,这需要花费很多时间(大约5-6个JOINS +嵌套的SELECTS)。目前我正在使用SET 'some key' JSON.stringify(query.result)
缓存此查询的结果。这工作正常,但我有一个不能缓存的列 - 它被称为commentsCount
。它必须始终是最新的。作为一个临时解决方案,我正在查询db这个特定字段,如下所示:
app.get('/post/getBySlug/:slug',function(req,res,next){
var cacheKey = req.params.slug+'|'+req.params.language; // "my-post-slug|en-us" for example
cache.get(cacheKey, function(err, post){
throw err if err;
if(post) {
db.getPostCommentsCount({ where: { id: post.id }}).done(function(err,commentsCount){
throw err if err;
post.commentsCount = commentsCount;
res.json(post);
next()
})
} else {
db.getFullPostBySlug(req.params.slug, req.params.language).done(function(err, post){
throw err if err;
cache.set(cacheKey, post);
res.json(post);
next();
})
}
})
})
但它现在仍然是我想要的,因为主DB仍然被查询。在REDIS中存储计数器是否有任何标准/良好做法?我的注释插入函数如下所示:
START TRANSACTION
INSERT INTO "Comments" VALUES (...) // insert comments
UPDATE "Posts" SET "commentsCount" = "commentsCount" + 1 WHERE "Posts"."id" = 123456 // update counter on post
COMMIT TRANSACTION
我正在使用事务,因为我不想在不增加注释计数的情况下插入注释。作为一个“侧面”问题 - 最好在事务中进行2个SQL查询还是写一个触发器来处理递增计数器?
根据我的询问(我在评论中发布了gist的链接):
我们不计划超过2种语言(尽管有可能)
我制作了这些计数器是因为我必须按照语言保持计数器分开,能够通过这些单独的计数器进行排序,并且能够通过计数器的总和(所有语言的总数)进行排序 - 我发现很难在仍然返回那些行的同时,通过来自不同行的列的总和来进行查询...(在开头的计数器中存储了语言翻译)。
通常这个查询会查找哪些帖子存在具有特定'slug'和'language'的翻译(slug +翻译后的语言是唯一索引)。必须发布Morover帖子(isPublished = boolean),post.status必须'发布'(status = enum)或post.iscomingSoon必须为true(isComingSoon = boolean)。你知道我可以为这个查询添加什么索引/顺序吗?或者我应该删除限制?
在每个翻译表中,我都将语言保留为TEXT。它可以是例如en-us或zh-cn等。你认为我应该让它枚举还是我应该创建另一个表来存储语言并且只保留language_id的翻译?
作者实际上可以为null:)