开发者社区> 问答> 正文

Java缓存设计求助报错 

已解决

最近小弟一直有过困惑!

想在此了解下各位大虾的缓存是如何设计的! 我先说说我遇到的问题!不知道各位是如何解决的!

比如一张用户表 有 id,用户类型,帐号,密码 id:              主键 用户类型      聚集索引 帐号,密码    唯一索引
在代码中的缓存设计就会对应3个Map id              ->   map1.put(id,obj) 用户类型     ->   map2.put(用户类型1,set)    *set中保存的是用户类型=1的所有id 帐号,密码  ->   map3.put(帐号+密码,id)

这样可以很方便的把数据库关系映射在代码缓存中,可以很方便的操作!
但是有个问题就是,必须缓存整张表,并且不能做超时! 比如就上面这个例子 用3个用户  一个用户类型=1  两个用户类型=2 假如其中一个用户类型=2的超时了,他对应的缓存对象和缓存关系都应用删除!这时就存在一个问题了 就是再次查询用户类型=2的就只有一个用户了  因为用户类型关系的Map中 用户类型=2的Key存在。我就不再取查询数据库,而真实数据库存在用户类型为2的却有2个人

这种情况我想了2个方案感觉都不是很好 1.全缓存不做超时(很多不常用的数据也在缓存里 感觉有点不舒服) 2.超时不清除索引关系(这样在做查询列表的时候还要遍历检查这个对象在缓存中是否存在不存在查库再加入缓存感觉代价很高)

 

展开
收起
kun坤 2020-06-10 10:08:53 805 0
2 条回答
写回答
取消 提交回答
  • 精于基础,广于工具,熟于业务。
    采纳回答

    整个索引不就好了

    2020-06-10 17:26:43
    赞同 展开评论 打赏
  • 你缓存的目的是干什么?我感觉你是好几个场景。######回复 @foodon : 上面那只是一个简单的举例而已 主要问题就是在查询列表!######回复 @SandKing : 缓存是为了加快常用功能的速度,但你这几个加到缓存的内容我没弄清作用。我猜想:1、以uid为key缓存用户是为了经需要用户的信息;2、以username为key缓存password是为了登陆;3、这就弄不懂是什么场景了。######缓存的目的 但然是让查询更快啊######没有人么  这么快 就要沉了。。。###### 是这个样子的
    缓存的确是要让查询更快,但是缓存主要是为了多次查询的某一条记录做的
    比如说99%的用户需要查询第99条记录,那么把这条记录写入缓存是比较好的方案
    但是缓存是有局限性的,像你要统计全表有多少的2类用户,这不可以用缓存来做的,因为这里涉及到的记录是全表中的记录,所以你的问题2是不合适的,因为如果要实现这个功能就不要用缓存做
    再一个一般缓存应该不是用时间触发超时的,一般是在每次你向缓存中插入一条记录的时候统计当前缓存中的记录条数,如果达到了缓存大小的极限,那么会用一种选择算法把其中的一条记录去掉。记住这里是向缓存中插入记录,不是所有插入记录的情况。对数据库写操作的时候要直接操作数据库的,只有读操作才经过缓存,而且如果是update的话要判断是不是某条记录与缓存中记录不一样了,那样要修改缓存中的记录。其实对于哪些记录要进缓存也是要用算法判断的,选择大多数用户会查询而且一般不修改的是比较好的可以进缓存的记录。
    加缓存的问题很多的,建议查oracle数据库缓存的原理。数据库也是有缓存的,一般不用我们来在程序内设置缓存,如果你想要这方面的知识那么看看oracle缓存一些基本的原理吧。 ######如果一个玩家上线 要保证他的所有请求都比较快,所有的请求都不能超过20毫秒 20毫秒中要包括你的业务逻辑+数据查询等等######你说的这种是对要求不是特别高的情况,我们在做游戏的时候你更具用户要查询一个用户的列表什么的。对查询速度要求比较高! 我要做的是查询 全查询缓存 ,插入 更新 同时修改缓存和数据库###### 不建议用缓存,根本就是根据索引查对象。。
    没有达到缓存的基本要求。。 ######这样做 比你查询库 快太多太多了######你是做的缓存吗?怎么这么复杂?缓存一个对象不可以吗?不太理解你的需求。###### 你这等于就是把缓存做数据库来用,所以那个超时移除可以去掉了.
    至于那些不常用的数据,可以想办法做到要用到时加载,不用时剔除,这块才是你需要设计的地方,比如说针对这种数据启用超时. ######基本上就是这个意思! 用的时候加载OK没问题,不用时剔除这个就会出现我上面说的这个情况了!######

    引用来自“李三乎”的答案

    是这个样子的 缓存的确是要让查询更快,但是缓存主要是为了多次查询的某一条记录做的 比如说99%的用户需要查询第99条记录,那么把这条记录写入缓存是比较好的方案 但是缓存是有局限性的,像你要统计全表有多少的2类用户,这不可以用缓存来做的,因为这里涉及到的记录是全表中的记录,所以你的问题2是不合适的,因为如果要实现这个功能就不要用缓存做 再一个一般缓存应该不是用时间触发超时的,一般是在每次你向缓存中插入一条记录的时候统计当前缓存中的记录条数,如果达到了缓存大小的极限,那么会用一种选择算法把其中的一条记录去掉。记住这里是向缓存中插入记录,不是所有插入记录的情况。对数据库写操作的时候要直接操作数据库的,只有读操作才经过缓存,而且如果是update的话要判断是不是某条记录与缓存中记录不一样了,那样要修改缓存中的记录。其实对于哪些记录要进缓存也是要用算法判断的,选择大多数用户会查询而且一般不修改的是比较好的可以进缓存的记录。 加缓存的问题很多的,建议查oracle数据库缓存的原理。数据库也是有缓存的,一般不用我们来在程序内设置缓存,如果你想要这方面的知识那么看看oracle缓存一些基本的原理吧。
    呃,你现在做的都是数据库要做的功能啊。数据库本身是有缓存功能的。你们没有数据库工程师么,这些不应该是代码里要考虑的内容啊。你的总的要求就是要快速的进行数据查询,这应该是数据库里存储过程的功能啊。 平时用代码写的话做个小的缓存自己用还可以,要这样大型的用数据库自己来处理是最好的。 如果非要自己做的话,可以借鉴memDB的思路,我们可以在内存中虚拟一个数据库,按照jdbc driver的接口实现存储在内存中的数据库,你可以让一个专门的服务器用来定期把修改写入本地数据库。 这种情况真心不建议自己做缓存
    2020-06-11 14:01:26
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载