首页新闻找找看学习计划

缓存Table的实现。

0
悬赏园豆:50 [待解决问题]

现有两张表 :Countries(id,name),缓存表Cached_Countries(id,name)

对表Contries查询时的逻辑如下:

1:根据查询条件(where-clause),判断是否能从Cached_Contries中查询。

2:如果能从Cached_Countries中查询,则直接从Cached_Countries表中查询,并返回。

3:如果不能从Cached_Countries中查询,则从Countries中查询,并把查询结果插入到Cached_Countries表中。

 

 

难点在于:如何判断是否应该从Cached_Countries中查询。

如:第一次执行sql 查询条件为:”id>0“, 同时把id>0的结果写入到了Cached_Countries表中;每二次执行sql查询条件为:”id>1“。 明显肉眼看出,id>0的结果是包含id>1的结果的, 这样就能直接从Cached_Countries中查询。

 

"id>0" contains "id>1"

"id>0 or name='China'" contains "id>0"

 

参考:http://stackoverflow.com/questions/20042742/how-can-i-know-a-where-clause-query-results-contains-another-where-clause-query

 

这只是一个引子,,, 我所说的Countries表其实是对应了一个网络服务的,, 基于这个网络服务我们可以作查询 。。  大数据量查询的时候 ,大家知道多慢了,所以我想做缓存,做比较灵活的缓存,哪种key-value形式的类http缓存大家就不用讨论了。

由于数据更新从而使缓存失效的情况,暂且不讨论(这个仅仅是业务逻辑设计的问题)。 

 

如何实现这个功能呢??

如坐夕阳的主页 如坐夕阳 | 初学一级 | 园豆:152
提问于:2013-11-18 18:46
< >
分享
所有回答(3)
0

你还是别用这种无聊的设计了,直接从数据库取,数据库没你想象的那么脆弱,有时候对缓冲的后数据的查询性能还不如直接去数据库取,毕竟数据库有索引等能提高查询速度,而缓存没有

56180825 | 园豆:1128 (小虾三级) | 2013-11-18 19:28

 相信我,这只是一个引子,,, 我所说的Countries表其实是对应了一个网络服务的,, 基于这个网络服务我们可以作查询 。。  大数据量查询的时候 ,你就知道多慢了。 

支持(0) 反对(0) 如坐夕阳 | 园豆:152 (初学一级) | 2013-11-19 09:06

@如坐夕阳: 所谓大数据,多半是数据库设计不合理造成的,当然确实有真的大数据,您公司真有那么大的访问量?企业级开发数据库已经完全够你用了

支持(0) 反对(0) 56180825 | 园豆:1128 (小虾三级) | 2013-11-20 22:39
0

参考NopCommerce的设计:

1、Country全部缓存,每次取的时候都从缓存取,如果没有Country的缓存,就从数据库取。

2、添加、更新都使Country的缓存作废,从而下次取Country的时候,全部从数据库重新取。

这个方法非常适合非业务数据的缓存,我把这种缓存封装到了Repository,这样当我需要Country或者Role之类的东西,根本不需要管是从缓存来的还是从数据库来的。

Shine Ss | 园豆:214 (菜鸟二级) | 2013-11-18 19:46

相信我,这只是一个引子,,, 我所说的Countries表其实是对应了一个网络服务的,, 基于这个网络服务我们可以作查询 。。  大数据量查询的时候 ,你就知道多慢了。 

全部获取是不现实的。。

支持(0) 反对(0) 如坐夕阳 | 园豆:152 (初学一级) | 2013-11-19 09:07

@如坐夕阳: 那就给你的查询做个索引器。比如id>0转换成一个索引序列,后续的查询一样转换成索引序列,两个序列求差集,差集为0表示不需要从数据库(或网络服务)取,要取也只取差集的内容,取回来后更新索引序列。

支持(0) 反对(0) Shine Ss | 园豆:214 (菜鸟二级) | 2013-11-19 09:29
0

缓存设计最粗鲁的方法就是1秒缓存法,当然即使一秒缓存法已经能够改善程序超过80%的性能。

更多的设计只是为了让缓存有更高的命中率同时解决缓存大面积失效的服务器雪崩效应。

如果要是俺来做,俺可能不会这样的缓存。当在Countries根本不需要缓存,即使缓存了也无效,太大的数据量缓存改善不了任何效果,任何查询尽量的转换为主键查询,查询语句md5,聚集一个key集合,当伴随发生更改或者删除操作的时候,触发key 失效,大体这样,实际上根据不同的场景然后调整。

````` | 园豆:14268 (专家六级) | 2013-11-19 09:40

1:Countries表的查询是通过在线的Web服务完成的。

2:针对查询条件来说, 用户可以指定任何查询条件 。所以你说尽量只针对主键查询不太可行。

3:或许我理解错你的意思,, 你把whereclause用md5算法算出一个key,然后再去匹配。 这个情况有点多哟。 如"id=1","ID=1","ID = 1" ;"id = 1 or name='beijing'","name = 'beijing' or id=1"都是一样的。

这样缓存命中率是否会降低。。 针对我说的第一次查询了“id>0”,也想要"id>1"使用缓存的需求怎么做?

支持(0) 反对(0) 如坐夕阳 | 园豆:152 (初学一级) | 2013-11-19 10:39

@如坐夕阳: 即使whereclause 的情况  并不需要太多的处理,因为当索引过后,即使一个亿的数据也会相当的快。为这个情况下缓存怎么处理都不会有太多的方案,并且当搜索一次之后 会被缓存,这已决定了大部分的缓存会被击中。id=1  这些的问题也不是需要考虑的,因为依然即使得到的md5不一样 但是依然会进入自己缓存命中里,并且程序里面的数据库查询一次,写完了 差不多恒定了,不会有那么多的方案。

这块推荐一本书《构建高性能web》是腾讯的基础研发团队出的,相信不会超过腾讯。所以那本书讲的大多数都已经够用了。

支持(0) 反对(0) ````` | 园豆:14268 (专家六级) | 2013-11-19 12:20

@imfunny: Thanks, 你说的书我去看看,看是否有启发。 不光是缓存命中的问题,还有缓存是否正确的问题。。

举个例子。

我第一次查询了id>5的所有值,, 那么我就把id>5所有的记录缓存了下来;下一次查询id>1时,如果直接通过缓存查询,依然会查询到记录,但是查询结果是不完整的。

 

我想可能我没有完全静态出我想描述的问题吧。

支持(0) 反对(0) 如坐夕阳 | 园豆:152 (初学一级) | 2013-11-19 13:15

@如坐夕阳: 如果直接通过缓存查询,依然会查询到记录,但是查询结果是不完整的。

根本不会这样来操作,依然会是数据库。

缓存设计其实不需要过度设计,过度设计了反而会增加复杂性并且难以维护。

楼主看下那本书应该会有很多收获的。

数据库只要别乱写查询语句不会那么龊的了。

支持(0) 反对(0) ````` | 园豆:14268 (专家六级) | 2013-11-19 13:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册