最好的方式是对程序是透明的,程序猿们不用关心背后的存储细节问题,比如是分表了还是分库了。
分表1
Deal.table_name = "deals_100"
deal = Deal.new
deal.price = xxx
deal.save
上面写法如果效率比较低的话(诱发底层的很多验证和表的meta数据获取),这样稍微会好些:
if(Deal.table_name != "deals_100"
Deal.table_name = "deals_100"
end
deal = Deal.new
deal.price = xxx
deal.save
这种问题是程序公布了自己的分表策略,每回或者在变更的表的时候,需要写代码来切换表。
分表2
把分表的任务放在sql层,即交给dbms执行sql前,处理一下。
比如这个插件:https://github.com/cookpad/arproxy
+-------------------------+ +----------+ +----------+ +------------------+
| ActiveRecord::Base#find |--execute(sql, name)-->| MyProxy1 |-->| MyProxy2 |-->| Database Adapter |
+-------------------------+ +----------+ +----------+ +------------------+
可以在MyProxyN内对sql进行处理
这种处理方法的好处是对程序透明了,但坏处是直接替换sql。
简单的crud操作还好,但对逻辑比较复杂的操作,比如发杂的连表查询等,替换策略可想而知。
分表的折中处理
分库1
待续。。。
。
。
。
参考:
dynamic table names for Active Record models
How to change ActiveRecord's table name during runtime