基于客户端的网站的最佳数据库策略(Ruby on Rails)

wnvonmuf  于 2023-10-17  发布在  Ruby
关注(0)|答案(3)|浏览(100)

我已经建立了一个很好的网站系统,迎合了一个小利基市场的需求。在过去的一年里,我一直在通过使用Capistrano将软件的副本部署到我的Web服务器来销售这些网站。
在我看来,这些网站的唯一区别是数据库,CSS文件和用于个人客户端图形设计的一小部分图像。
其他一切都是一样的,或者应该是...现在我已经部署了大约20个这样的网站,用相同的代码更新它们变得很麻烦。这个问题只会变得更糟。
我想我应该重构这个系统,这样我就可以使用一组部署的Ruby代码,通过传入请求的URL动态选择正确的数据库等。
似乎有两种处理数据库的方法:

  • 使用多个数据库,每个客户端一个
  • 使用一个数据库,每个表中有一个client_id字段,还有一个额外的“client”表

多数据库方法目前对我来说是最简单的,因为我不必重构应用程序中的每个模型来将client_id字段添加到所有CRUD操作中。
然而,每次我想迁移数据库时,都要为几十个或几百个不同的数据库运行“rake db:migrate”,这将是一个麻烦。显然,这可以通过脚本来完成,但它闻起来不太好。
另一方面,每个客户端在“items”表中将有20 K-50 K项。当items表中有50万或100万个条目时,我担心全文搜索的速度。即使在client_id字段上有一个索引,我怀疑如果这些项被分隔到不同的客户端数据库中,搜索会更快。
如果任何人对处理这个问题的最佳方法有一个明智的意见,我很想听听。

b09cbbtk

b09cbbtk1#

我决定使用多数据库方法。这对我来说是最简单的方法,因为我不需要重新编写整个应用程序。
我要做的是在application_controller中添加一个before_filter,这样它就适用于所有的控制器。比如这样:

before_filter :client_db         # switch to client's db

然后,在application_controller.rb中,我将包含这样的内容:

def client_db
    @client = Client.find(params[:client_id]) 
    spec = Client.configurations[RAILS_ENV] 
    new_spec = spec.clone 
    new_spec["database"] = @client.database_name
    ActiveRecord::Base.establish_connection(new_spec) 
 end

然后,像example.com?client_id=12345这样的URL将选择正确的数据库。
由于我在Mongrel前面使用Apache作为代理,Apache将根据客户端的网站URL向所有请求添加正确的client_id。所以client_id实际上并不是用户看到的URL的一部分。它只会在Apache和Mongrel之间传递。我不确定我是否正确地解释了这一点,但它的工作和保持事情干净和简单。
如果我决定将来需要使用单个数据库,我可以重构所有代码。目前,这似乎是最简单的方法。

eoxn13cs

eoxn13cs2#

使用单独的数据库(包括您已经列出的数据库)有以下优点:

  • 当您有数百万个大文本blob要搜索时,全文搜索将变得缓慢(取决于服务器的能力)。
  • 分离数据库将使每个客户机的表索引速度更快。特别是,如果你接受了一个新的大客户,它可能会让你的一些早期客户感到不安。突然间,他们的应用程序将受到影响,没有明显的原因。同样,如果您的硬件容量不足,这可能不是问题。
  • 如果您删除了一个客户端,那么只打包它们的数据库比通过client_id删除所有相关行要稍微干净一些。如果他们后来改变主意,也同样干净地恢复他们。
  • 如果任何客户要求额外的功能,他们愿意支付,你可以分叉他们的数据库结构,而不修改任何人的。
  • 悲观主义者:更少的机会,你意外地破坏所有客户端数据的错误,而不是只是一个客户端的数据。;)

话虽如此,单DB解决方案可能更好:

  • 您的DB服务器的功能使大型单表成为不成问题的问题。
  • 你客户的数据库保证保持一致。
  • 您不必担心是否能够将每个人的数据分隔开来,以便归档/恢复或发生灾难时使用。
jv4diomz

jv4diomz3#

我会选择使用客户端ID的单个数据库--通过使用某种形式的基本模型,以及一个命名范围来将任何操作范围限定到该客户端的ID,您应该能够使重构不那么痛苦。
您可以使用索引库(如Ferret)或类似的沿着工具来处理全文搜索变慢的问题。这将是一个问题,无论如何,一旦一个客户端的数据库变得很大,所以你可能需要实现这两种方式。

相关问题