SAAS and Multi-tenancy in Symfony2?


SAAS and Multi-tenancy in Symfony2?

我已经使用Symfony将近2年了,到目前为止,我构建的每个项目都是专门为每个客户端部署的(即一个客户端、一个代码库、一个数据库)。

比方说我有一个项目管理应用程序,我想为许多客户端部署它。假设客户端将使用我在系统中构建的任何功能,如果我为每个客户端部署不同的代码库(因此,不同的数据库),以下是我预见到的问题:

  1. 推动错误修复和升级将是痛苦的。我需要将它推送到我部署的每个存储库中。如果我有50个客户使用同一个应用程序,它就不会很好地扩展。

  2. 管理是痛苦的。我如何为自己构建一个管理系统,将所有项目拉到一个HTML表中?毕竟,每个客户端都有自己的数据库,对吧?为了让我对所有客户的所有记录做任何有意义的事情,我需要一种一次性查看他们所有数据库的方法。。我不认为Symfony允许。(我不确定)

  3. 用户帐户问题。如果一个用户碰巧在多家公司工作,所有公司都在使用我的项目管理应用程序,该用户必须多次注册。(我知道如果我使用oauth,这是可以绕过的,但如果可以的话,我尽量不去那里)

以下是我思考并在一定程度上尝试过的解决方案。


解决方案1

为我的所有客户提供一个数据库和一个代码库。项目将放在一个表下,发票放在一张表下,所有这些都用自己的client_id标记。用户可以被分配到项目,因此无需多次注册。

这并不难创造。但是,如果不同的客户需要不同的发票列,会发生什么?我的发票表将不断扩展(使用不同客户需要的不同字段),并且每行可能包含许多空字段。更不用说,我的Invoice实体的文件大小会增加,每次出现新的自定义时,我都必须更新数据库模式。


解决方案2

一个数据库,其中每个客户端都有自己的表前缀。所以对于客户端A,我可以使用客户端项目、客户端发票、客户端配置等。

如果每个客户都想自定义自己的字段,那么这是非常理想的。但是,这是否意味着我需要为进入系统的每个新客户端创建新的实体和表单类?对于这个解决方案,我需要用我得到的每一个新客户端更新数据库模式。


目前,我正在尝试无模式数据库(mongo和couch),希望在不需要预先指定表模式的情况下,我可以轻松地实现解决方案1。但我仍在尝试,在我不熟悉mongo和Symfony沙发的问题的情况下,要想部署一款适合生产的应用程序,还有很多路要走。


所以,这就是我的困境。作为一名自学成才的程序员,我觉得我的知识中有很多漏洞需要填补(而不是CS背景的人)。网上没有太多地方在谈论Symfony 2和多租户(也许我找错了)。如果有人能给我指一个更清晰的方向,也许是最佳实践,示例项目,我会非常感激的!

顺便说一句,我计划在Symfony的最新版本(目前为2.3.2)中执行此操作。

提前感谢各位。

我也在使用Symfony2类似的时间(从一个BETA开始),我建议您使用解决方案#1。如果你要使用SaaS,你不能因为你写的原因(主要是更新/升级的问题)向客户发送代码。整个麻烦将集中在用户管理上——哪个用户可以访问哪些数据,属于哪个组、公司等等。如果做得好,所有其他事情都将以与用户无关的方式进行编码。对于不同公司的不同要求,你应该怎么做?使这些特征成为configurable。您可以在不同级别上实现这一点:

  • 简单的实体属性:每个表中都有一个attributes字段,并将所有内容保存为JSON、YAML或其他动态结构化内容
  • 通用配置:有一个存储实体基本配置的地方(用我上面写的方法),并允许用户从那里管理新功能,所有更改都传播到简单的实体
  • 实现我称之为Entity Parameters Pattern的东西——设计数据库表,其中包含不同级别的参数类型、参数值以及与其他实体的关系,然后制作通用的可配置参数类型,可以应用于任何具有预定义含义的地方。例如,"preferred_treason"是一个类型为"choice_string"的参数,包含配置"春季、夏季、秋季、冬季",并且当附加到给定实体时,将始终呈现具有选项的<select>字段,并保存与实体和参数类型相关的选定值

此外,解决方案#1还有一个无与伦比的优势——即使你想在最后发布代码,它也可以处理多家公司。你只需要屏蔽添加更多内容的能力。:)

这个问题被标记为Symfony2,但它确实不应该。不管你使用的是什么框架,你都应该从代码中抽象出你的应用程序设计,然后把框架作为一个简单的工具来顺利地完成工作。我想说,即使考虑到前一句话,我也绝对爱上了Symfony2。:)

我知道这是一个老问题,但对其他人来说可能很有用。

我同意@Tomasz和one database的解决方案#1——所有租户都在一个数据库中。这里最大的问题是正确的数据库设计,以解决进一步的安全问题:对资源的访问必须由应用程序控制,以防止租户之间的未经授权的访问。另一方面,我们可以轻松实现,因为我们只使用一个数据库实现单个应用程序。

关于Symfony2和转移到SaaS模型的好文章:http://www.browserlondon.com/blog/2015/01/moving-to-a-saas-model-with-symfony2/

关于在SaaS平台中设计数据库的"必读"文章——独立于平台的模式:http://labs.octivi.com/database-design-in-saas-platforms/