对Rails中的多租户与多数据库应用程序的任何想法

我们的应用程序当前为每个客户端生成一个新数据库。 我们开始怀疑是否应该考虑将其重构为多租户系统。

我们应该考虑哪些利益/权衡? 在Rails中实现多租户应用程序的最佳实践是什么?

我一直在研究同样的事情,只是发现这个演示文稿提供了一个有趣的解决方案:使用Postgre的模式(有点像名称空间)来分离数据库级别的数据,同时保持所有租户在同一个数据库中并保持(大部分)透明轨道。

在Rails中编写多租户应用程序 – Guy Naor

多租户系统将为您介绍一系列问题。 我的快速想法如下

  • 必须检查和重构所有SQL以包含ClientId值。

  • 必须检查所有索引以确定是否需要包含ClientId

  • 生产中的开发人员/系统管理员在SQL语句中的错误将影响您的所有客户。

  • 数据库损坏/问题将影响您的所有客户

  • 您有一些数据隐私问题,因此糟糕的代码/实现可能允许customerA查看属于CustomerB的数据

  • 以沉重/激进的方式使用您的系统的客户可能会影响其他客户对性能的感知

  • 根据个人客户偏好调整静态数据变得更加复杂。

我确定还有其他一些问题,但这些是我最初的想法。

这取决于你在做什么。

我们正在为印刷行业制作MIS程序,跟踪库存,员工,客户,设备,并进行一些严肃的计算,以估算基于大量输入变量执行作业的成本。

我们期待为每个客户提供非常大的数据库,目前我们有170个表。 为了存储client_id,几乎每个表都添加另一列会伤害我的大脑。

我们目前处于我们计划的测试阶段,以下是我们遇到的一些问题:

  • 迁移: Rails假设您只有1个数据库。 您可以针对多个数据库进行调整,迁移就是其中之一。 您需要自定义rake任务才能将迁移应用于所有现有数据库。 准备好做很多麻烦,因为迁移可能在一个数据库上成功,但在另一个数据库上失败。
  • 产卵数据库:如何创建新的数据库? 从SQL文件复制现有数据库,还是运行所有迁移? 如何在表创建系统和实时数据库之间保持模式一致?
  • 连接到适当的数据库:我们使用cookie来存储映射到正确数据库的唯一值。 我们在Authorized控制器中使用beforefilter,该控制器从ActionController获取,从该唯一值获取db并在ActiveRecord :: Base的子类上使用establish_connection方法。 这允许我们从公共数据库中获取一些模型,从客户端的特定数据库中获取其他模型。

如果您对这些问题有任何疑问,我可以提供帮助。

我个人没有任何经验,但在2009年Ruby Hoedown的闪电谈话中,Andrew Coleman提出了一个他设计的插件,用于带有子域的rails中的多租户数据库。 您可以查看闪电谈话幻灯片 ,这里是acts_as_restricted_subdomain存储库 。

你为什么这样? 您是否在用户之间进行了大量聚合,或者您是否产生了太多的数据库? 您是否考虑过每个租户使用SQLite文件而不是共享数据库服务器(因为多租户应用程序通常都是低调的,并且不需要那么多并发)?