关联表查询结果的 Redis 缓存如何设计 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3630cn2023
V2EX    Redis

关联表查询结果的 Redis 缓存如何设计

  •  
  •   3630cn2023 2023 年 12 月 25 日 via Android 3951 次点击
    这是一个创建于 780 天前的主题,其中的信息可能已经有所发展或是发生改变。
    表 T1(id, project_id, score), project 表
    T2(id, type),两个表关联查询的接口 A(userId),B(projectId),如果用 userId ,projectId 作为两个接口的 Redis 缓存 key ,那么接口 C 用通过表 1 的 id 更新数据的时候,A ,B 接口的 Redis 缓存如何更新?
    第 1 条附言    2023 年 12 月 26 日
    表 T1(user_id, project_id, score),是 user_id 写漏了
    第 2 条附言    2023 年 12 月 26 日
    表 T1(id ,user_id, project_id, score),手机编辑不好用
    9 条回复    2023-12-26 17:03:11 +08:00
    matrix1010
        1
    matrix1010  
       2023 年 12 月 25 日
    这类问题没有完美解决方法,想尽可能自动处理的话可以参考 rails 的 Russian doll caching 。另外推荐看看这篇文章 https://blog.the-pans.com/when-and-how-to-invalidate-cache/
    bubble21
        2
    bubble21  
       2023 年 12 月 26 日
    业务层使用 Spring-Cache 呢 @Cacheable,@CacheEvict ?
    InkAndBanner
        3
    InkAndBanner  
       2023 年 12 月 26 日
    首先问题描述的挺不清晰的
    1. useId 是哪个表的 id ? T1 吗?
    2. 那“如果用 userId ,projectId 作为两个接口的 Redis 缓存 key” 意思是分别做 AB 两个接口的返回值缓存?还是 UserId+projectId 做 key ,score 做 value ?
    如果缓存的是连表查询的结果,并且假设你问的是更新方案的思路 那么俺觉得任意一表有写操作的时候,就应该把缓存失效掉。如果并发不高 直接更新缓存也是可以的。2 楼说的是具体的实现方案了。
    3630cn2023
        4
    3630cn2023  
    OP
       2023 年 12 月 26 日 via Android
    @matrix1010
    感谢分享这篇好文章,看了大致思路是建一个 key 的关联表( A ,B ,C 接口缓存的 key ),C 接口更新数据的时候,通过这个 key 关联表查处 A ,B 接口哪些 key 要更新
    这样做成本太大了,就跟你说的一样,这类问题没有完美解决方法,这个文章的思路并不通用,
    3630cn2023
        5
    3630cn2023  
    OP
       2023 年 12 月 26 日 via Android
    @bubble21
    @3630cn2023
    A ,B 接口的 key 如何设计,C 接口更新的时候如何更新 A ,B 接口的缓存?
    其实问题就是一份数据被缓存了两份,如何保证数据一致性
    3630cn2023
        6
    3630cn2023  
    OP
       2023 年 12 月 26 日 via Android
    @matrix1010 应该说这个文章的实现不通用,思路是可以通用的
    whoami9426
        7
    whoami9426  
       2023 年 12 月 26 日
    对于读多写少的场景可以这样设计:
    0. 缓存 key 上添加 sql 的标识以及参数: com.xx.xxmaaper.selectX1: userId: projectId
    1. 获取 sql 中关联的表名,设计存储这样的 json, json 中的 key 为表名,value 为 缓存过的相关的 sql 标识,设个过期时间取个名放到 redis 中
    ```json
    {
    "T1":["com.xx.xxmaaper.selectX1"] ,
    "T2": ["com.xx.xxmaaper.selectX1"]
    }
    ```
    2. 写一个拦截器,拦截修改更新的 sql ,获取上一步中的 json,如果更新的 sql 中所涉及的表存在于这个 json key 中,前缀删除 redis 中这个 key 的 values 也就是缓存过的 sql 结果,同时更新这个 json.
    MIUIOS
        8
    MIUIOS  
       2023 年 12 月 26 日
    我觉得这是缓存颗粒度大小的问题,根据场景来决定缓存的颗粒度
    sampeng
        9
    sampeng  
       2023 年 12 月 26 日
    这就是一个缓存设计问题。可大可小。引入缓存就要仔细解决缓存不一致问题。连表查这种缓存不一致是最熬人的。没什么特别通用的办法。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1133 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 17:32 PVG 01:32 LAX 09:32 JFK 12:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86