【问题标题】:SAAS and Multi-tenancy in Symfony2? [closed]Symfony2 中的 SAAS 和多租户? [关闭]
【发布时间】:2013-07-27 16:26:36
【问题描述】:

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

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

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

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

  3. 用户帐户问题。如果一个用户碰巧为多家公司工作,他们都使用我的项目管理应用程序,那么该用户必须多次注册。 (我知道如果我使用 oauth 可以避免这种情况,但如果可以的话,我会尽量不去那里)

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


解决方案 1

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

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


解决方案 2

每个客户端都有自己的表前缀的数据库。所以对于客户端 A,我可以使用 clientA_projects、clientA_invoices、clientA_configuration 等。

如果每个客户都想自定义他们的字段,这是理想的选择。但是,这是否意味着我需要为进入系统的每个新客户端创建新的实体和表单类?看起来使用此解决方案,我需要使用我获得的每个新客户端更新数据库架构。


目前,我正在试验无模式数据库(mongo 和 couch),希望无需预先指定表模式,我可以轻松实施解决方案 1。但我仍在尝试,在我敢于部署可用于生产的应用程序之前还有很长的路要走,我不熟悉 Symfony 的 mongo 和 couch 问题。


所以,这就是我坚持的地方。作为一名自学成才的程序员,我觉得我的知识有很多需要填补的漏洞(与具有 CS 背景的人相反)。网上没有多少地方在谈论 Symfony 2 和多租户(也许我找错了东西)。如果有人能指出我更清晰的方向,也许是最佳实践、示例项目,我将非常感激!

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

提前谢谢各位。

【问题讨论】:

  • @Lu0-dezhang 有没有可能分享你的结果?我正在使用 Symfony3 开始一个新的 SaaS 应用程序,但对数据库和 Symfony3 项目组织一无所知,所以....很难吗?

标签: php symfony doctrine-orm saas


【解决方案1】:

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

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

此外,解决方案 #1 有一个无与伦比的优势 - 即使您想在最后提供代码,它也可以处理不止一家公司。您只需要掩盖添加更多内容的能力。 :)

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

【讨论】:

    【解决方案2】:

    我知道这是一个较老的问题,但对其他人有用。

    我同意@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/

    【讨论】:

      猜你喜欢
      • 2018-08-20
      • 2014-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-28
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      相关资源
      最近更新 更多