2011-05-06 107 views
13

我在Heroku上构建了部署Rails 3应用程序,我想知道是否有任何关于如何处理我的模型中的多租户的建议。半年前,这里发布了一个相关的问题(#3776593),但没有得到很多答案。我也看过Guy Naor's presentation on writing multi-tenant applications with Rails,但似乎3个建议的解决方案中的2个不适用于Heroku。我会链接到这些,但新的Stackoverflow用户限于2个超链接。在Heroku上编写多租户Rails 3应用程序

我也遇到了以下工具:

只是想知道,如果你有任何的多租户宝石或简单的护栏,多体验租赁宝石。似乎最简单的解决方案是简单地将所有模型中的belongs_to放在帐户下,但我真的想知道您在真实世界中使用的是什么!

+1

出于好奇,你是如何解决这个问题的? – kmurph79 2012-06-20 00:52:50

回答

6

这些方法的范围从“无共享”(通常意味着每个租户有一个数据库)到“共享所有”(通常意味着每个表包含来自许多租户的行)。下面的频谱可以按照隔离度,成本(即每租户的成本)来分解,并且容易实现灾难恢复。

  • 每个租户一个数据库;最高的成本,最高的隔离度,最简单的恢复。
  • 每个租户一个模式;其他两家之间的成本较高,隔离良好,恢复相当容易,但恢复通常会降低其他租户的性能。
  • 租户分享表格;成本最低,隔离度最低(共享表),难以实现的灾难恢复(恢复通常意味着为每个表恢复一些行)。对于其他租户来说,恢复通常会“降低”性能。

所有这些在某种程度上都是平台特定的。当dbms禁止查询访问多个数据库时,“每个租户一个数据库”的隔离度最高。但是有些平台允许跨多个数据库查询。

MSDN有一个体面的文章,达到高点:Multi-Tenant Data Architecture

但是,如果您仅限于Heroku,则必须选择Heroku支持的选项。我不知道这些选项可能是什么,但我知道你最好不要在开发中使用SQLite。 Heroku部署将在PostgreSQL上运行;你需要针对PostgreSQL进行开发。

6

作为multitenant gem的作者,我显然有偏见,但我真的相信这是一个很好的解决方案!宝石的目标是简化这种常见的应用需求,并使其实现微不足道。

“老派”的另一种选择是使用rails对象链来确保所有查询都是通过关联的父对象完成的。这种方法的问题是你的租客对象成为has_many关联的倾倒地。

class Tenant 
    has_many :users 
end 
# query for users in the current tenant 
current_tenant.users.find params[:id] 

多租户gem通过确保生成的所有查询自动识别当前租户来解决此问题。它还确保创建新记录并自动分配给当前租户,因此您不需要添加任何特殊的before_save回调。

例如:

Multitenant.with_tenant current_tenant do 
    # queries within this block are automatically 
    # scoped to the current tenant 
    User.all 

    # records created within this block are 
    # automatically assigned to the current tenant 
    User.create :name => 'Bob' 
end 
+3

嗨ryan,你为什么没有使用Multitentant.with_tenant的方式进入default_scope? – rafamvc 2011-07-28 15:34:04

2

我即将踏上这家合资公司(实现多租户,一个小的Rails应用程序),并同时做研究,我无意中发现了这个帖子SO。

令人惊讶的是,没有人提到RyanB使用Heroku支持的PostgreSQL模式实现MT的精彩视频。

这里是屏幕视频的链接http://railscasts.com/episodes/389-multitenancy-with-postgresql

理念:

在Rails应用程序,我们可以设置为PG连接

 connection.schema_search_path = "schema1, schema2, ..." 

任何后续行动将在schema1如果发现相应的表有执行的搜索路径。否则,它将搜索schema2中的表格等等。与包括租户在内的整个应用模式一起公开,通常的做法是使除租户外的所有表都为空的公共模式。

新房客登记:

添加after_create功能,以您的租户模型来创建新租户一个新的模式,并创造一切(负载schema.rb)应用程序表(除了承租人)到这个新的模式。

用户:

当用户访问,subdomain1.myapp.com,发现从租户表该子架构和连接的搜索路径设置为“schema1,公众和认证用户。

请注意,我的意图只是为了涵盖解决方案背后的概念。请参阅RyanB的屏幕截图了解实际解决方案。

相关问题