You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免重复查询,高效从数据库向用户传递稳定数据?

优化方案:会话缓存+主动刷新,解决高频低变数据重复查询问题

这是个非常典型的高频低变数据优化场景,咱们可以通过会话缓存(Session)+ 数据更新时主动刷新缓存的组合方案来解决,既避免重复查询数据库,又能保证用户修改数据后能及时获取最新内容。

1. 用Session缓存用户基础数据

把用户的静态数据缓存到Session中,只有第一次访问、Session过期或者缓存被主动清除时,才去查询数据库。修改后的中间件代码如下:

router.use(function(req, res, next) {
  // 先检查Session里是否已有缓存的用户数据
  if (req.session.userData) {
    // 把缓存数据挂载到req上,方便后续路由和EJS模板直接使用
    req.userData = req.session.userData;
    return next();
  }

  // 没有缓存时,再查询数据库
  const uid = req.user.id;
  req.getConnection(function(err, conn) {
    if (err) {
      console.log(err);
      return next("Mysql error, check your query");
    }
    // 注意:uid是唯一标识,查询结果取第一条即可
    const query = conn.query('SELECT * FROM user_profile WHERE uid = ? ', uid, function(err, rows) {
      if (err) {
        console.log(err);
        return next(err, uid, "Mysql error, check your query");
      }
      // 将查询到的用户数据存入Session缓存
      req.session.userData = rows[0];
      req.userData = req.session.userData;
      return next();
    });
  });
})

这样处理后,用户后续的导航操作都会直接读取Session里的缓存数据,不会每次都触发数据库查询,大幅降低数据库压力。

2. 在数据修改路由中主动刷新缓存

当用户修改姓名、用户名或企业信息时,执行完数据库更新操作后,必须同步更新Session里的缓存,避免出现“缓存与数据库数据不一致”的问题。示例代码如下:

router.post('/update-profile', function(req, res, next) {
  const uid = req.user.id;
  const updatedData = {
    name: req.body.name,
    username: req.body.username,
    company_info: req.body.company_info
  };

  req.getConnection(function(err, conn) {
    if (err) return next(err);
    // 先更新数据库
    conn.query('UPDATE user_profile SET ? WHERE uid = ?', [updatedData, uid], function(err, result) {
      if (err) return next(err);

      // 方案1:直接更新Session中的缓存(适合字段少的情况)
      req.session.userData = {...req.session.userData, ...updatedData};
      // 方案2:删除缓存,让下一次请求自动重新查询(适合更新字段较多的场景)
      // delete req.session.userData;

      res.redirect('/profile');
    });
  });
});

3. 补充注意事项

  • Session过期时间:可以根据业务需求设置合适的Session过期时间,比如1-2小时,用户长时间不操作后,Session会自动过期,下一次访问会重新查询最新数据。
  • 多端修改场景:如果存在后台管理系统修改用户数据的情况,单纯依赖Session缓存可能会有延迟,这种情况可以考虑结合Redis等分布式缓存,或者在后台修改时主动触发用户缓存失效;但对于普通用户自行修改的场景,上面的方案完全够用。
  • EJS模板兼容:因为我们把userData挂载到了req对象上,EJS模板里可以直接用<%= req.userData.name %>、<%= req.userData.username %>来展示导航栏信息,和之前的使用方式完全兼容。

内容的提问来源于stack exchange,提问作者Cadmos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:46:37