文章不错。写了 read-thru, write-thru, write-behind 三种
还有一个策略是提前计算好全部 cache,然后在读之前就更新过期 cache
SELECT *
.. http://ruby-china.org/topics/5695
1 + 1
是可以解决问题的,就是 Rails 推荐的标准做法Eager Loading,把另一条转化成一个 IN 查询。但是这种 IN 查询在应用层是不容易缓存的。结果是这种 IN 查询每次都 Hit DB。而N + 1
的 N 条查询每条是简单的主键查询,不用任何额外的维护,利用现有的插件就可以维护缓存的一致性。从理论上讲,一个 web 系统可以做缓存优化的地方太多了。而你单揪着SELECT *
不放一点意思也没有,况且,那是个费力未必讨好的活儿。
pro tip:
If you really want to make a point about the performance of a particular thing, can you at least pretend you're using science?
再说一个,为什么要用 select *
呢,一条数据在不同的位置可能要调用不同的字段,全部取出来就可以缓存在内存,不同地方 select 不同的 col 缓存效率就低。当然也可以通过页面片段缓存,实际哪个好要看场合了。
首先是一句废话,用什么数据库取决于你的应用类型。
为什么要用 RDBMS,是因为数据本身之间存在关系啊。数据关系处理起来是很难的。要应用自己保证 ForeignKey Constraint 还是太麻烦了,所以才会出现各种 RDBMS。这也是为什么你总是要先 normalize 找出所有关系。
数据量上去之后,关系数据库的 join 查询都不能用
不是的。假如你知道你需要哪些 JOIN。Oracle 的 Table Cluster 可以把相关数据放在一起,这样即便是一个很大的 cluster,也是可以 JOIN 的。Google 开发的 F1 也是这么干的。
我更加坚定用 Mongodb 了
MongoDB 解决的完全不是同一类问题。你用 MongoDB,你对数据的假设是,对于任意一条记录,任何地点都可能对它发起写请求,且不存在某个地点发起写请求的次数特别多,此时你想要保证多数地点要可写。对,默认你已经跨地理分布的多个数据中心了。
另外,我在微博上提到过:Rails 的 ActiveRecord 在 3.1 以后,对于 n+1 有更先进的处理,通过 Eager Loading http://t.cn/zYnMxad 会转化成 in 查询,变成 1+1,而且 in 查询可以通过 cache server 的 multiget 方式来批量命中。
fork 了那个 cache,正在看如何改进这个。