首先感谢你的时间......在google,github和这里搜索完所有的搜索后,对于大字(分区/分片/ fedorate)更加困惑,我想我必须描述我遇到的具体问题并四处询问。
我公司的数据库处理大量用户和订单,因此我们以各种方式拆分数据库和表格,其中一些如下所述:
way database and table name shard by (maybe it's should be called partitioned by?)
YZ.X db_YZ.tb_X order serial number last three digits
YYYYMMDD. db_YYYYMMDD.tb date
YYYYMM.DD db_YYYYMM.tb_ DD date too
基本概念是数据库和表根据字段(不一定是主键)分离,并且有太多的数据库和太多的表,因此为每个数据库编写或神奇地生成一个database.yml配置并且每个表的一个模型是不可能的,或者至少不是最佳解决方案。
我查看了drnic的魔术解决方案,datafabric,甚至是活动记录的源代码,也许我可以使用ERB生成database.yml并在filter周围做数据库连接,也许我可以使用named_scope来动态决定用于查找的表名,但更新/创建操作受限于“self.class.quoted_table_name”,因此我无法轻易解决问题。甚至我可以为每个表生成一个模型,因为它的数量最多为30个。
但这不是干!
我需要的是一个干净的解决方案,如下面的DSL:
class Order < ActiveRecord::Base
shard_by :order_serialno do |key|
[get_db_config_by(key), #because some or all of the databaes might share the same machine in a regular way or can be configed by a hash of regex, and it can also be a const
get_db_name_by(key),
get_tb_name_by(key),
]
end
end
有人能让我高兴吗?任何帮助将不胜感激~~~~
答案 0 :(得分:1)
如果您想要特定的DSL,或者与遗留分片背后的逻辑相匹配的东西,您将需要深入了解ActiveRecord并编写一个gem来为您提供这种能力。您提到的所有现有解决方案都不一定是根据您的情况编写的。您可以根据自己的意愿改变任意数量的解决方案,但最终您可能需要编写自定义代码才能获得所需内容。
答案 1 :(得分:1)
听起来,在这种情况下,您应该考虑不使用SQL。
如果数据集很大并且可以表示为键/值对(稍微去标准化),则应该查看couchDB或其他noSQL解决方案。 这些解决方案快速,完全可扩展,并且基于REST,因此可以轻松扩展,备份和复制。
我们都用相同的工具解决了所有问题(相信我,我也尝试过)。
切换到noSQL解决方案然后重写activeRecord会更容易。
答案 2 :(得分:1)
案例二(只有数据库名称更改)很容易使用DbCharmer实现。您需要在DbCharmer中创建own sharding method,它将根据密钥返回连接参数哈希值。
其他两种情况不会立即得到支持,但可以轻松添加到您的系统中:
您实现了分片方法,该方法知道如何处理分片数据库中的数据库名称,这样您就可以对模型进行shard_for(key)
调用以切换数据库连接。
您可以添加如下方法:
class MyModel < ActiveRecord::Base
db_magic :sharded => { :sharded_connection => :my_sharding_method }
def switch_shard(key)
set_table_name(table_for_key(key)) # switch table
shard_for(key) # switch connection
end
end
现在您可以像这样使用您的模型:
MyModel.switch_shard(key).first
MyModel.switch_shard(key).count
并且,考虑到您从shard_for(key)
方法返回了switch_shard
个调用结果,您可以像这样使用它:
m = MyModel.switch_shard(key) # Switch connection and get a connection proxy
m.first # Call any AR methods on the proxy
m.count