环境:Java + Tomcat + Oracle
我们公司的开发框架有个叫做dict的基础服务,用于把数据库中保存的状态码“翻译”成用于显示的状态。
比如:0-有效,1-过期,2-失效这样的。
而数据库中有两张表专门用于保存这种转换关系我看到公司的实现是在tomcat启动时就把dict表中所有数据全部读出,然后缓存成全局的键值对。但是我在思考一个问题,由于dict中的记录有至少一半是千年都不一定用得上的,所以如果写个类用于缓存dict键值对,调用get时检查记录是否存在,如果不存在就查数据库取得之后返回
这样就能只缓存用到过的数据了,但是这样却导致查库的次数增加了(因为每次只取一条记录)所以我很纠结哪种实现性能更好些呢?希望各位赐教

解决方案 »

  1.   

    关键是“常用”与“不常用”本身就是个模糊而无法界定的概念,某个功能客户用得多自然对应的dict也查找得多。这个不能主观推断。然而,如果按以上诸君说的,那岂不是还得统计查找量,得不偿失,本来就是为了减少数据库访问才缓存的。我的意思也就是“常用”的和“不常用”的是完全混在一起的,我们无法把它们单独分拣出来,甚至连按常用的程度排序都不能。所以我们只能一视同仁的对待这些数据。在这样的情况下,是一次性全部进行缓存还是按需取出来缓存好些呢?前者可能浪费一些内存资源,后者可能使数据库访问次数增加。
      

  2.   

    除了楼上的办法外,可以参考ibatis式的缓存方式。
    ibatis的缓存设计是以SQL的hash值为KEY的,每个SQL第一次查询后结果会形成单独的缓存,SQL相同缓存就相同,SQL不同就算是同一张表也会读不同的缓存。
    这种设计方式是典型的缓存冗余+按需获取,连缓存内的查询都不需要了,不过缺点也比较明显,为了防止缓存膨胀的太厉害,需要设定缓存上限和替换策略。
      

  3.   

    楼上的说的我没听懂哦,这与sql语句有什么关联?况且我也不用考虑缓存上限和替换策略
    不知是我没说清楚还是怎样,我打个比方:
    比如我有一个dict{k,v}表,里面有几千条记录,因要频繁做依据k字段查v字段的操作所以考虑缓存
    方案一相当于在tomcat启动时执行sql='select * from dict',然后把全部记录转化成一个hashmap,从此再也不查表。优点:一共仅需查库一次;缺点:即使从未使用过的记录,也占用了内存。
    方案二相当于我查找k=123的值时,先在hashmap中找有没有,如果有则直接返回,如果没有则执行sql='select * from dict where k=123',将结果放入缓存然后返回。优点:仅缓存用过的记录;缺点:每次仅取一条记录,查库次数太多。
      

  4.   

    To 11楼:
    我在引文第一段最后一句已经说了,不统计读写次数,不进行分类。因为这样的做法是完全没有意义的,因为这根我的目的背道而驰了。To 12楼:
    没看懂哦~