139

我们的软件目前在 MySQL 上运行。所有租户的数据都存储在同一个模式中。由于我们使用的是 Ruby on Rails,我们可以轻松确定哪些数据属于哪个租户。然而,当然也有一些公司担心他们的数据可能会受到损害,因此我们正在评估其他解决方案。

到目前为止,我已经看到了三个选项:

  • 多数据库(每个租户都有自己的 - 几乎与每个客户 1 台服务器相同)
  • 多模式(在 MySQL 中不可用,每个租户在共享数据库中都有自己的模式)
  • 共享模式(我们当前的方法,可能在每列上都有额外的识别记录)

多模式是我最喜欢的(考虑成本)。然而,创建一个新帐户并进行迁移似乎非常痛苦,因为我必须遍历所有模式并更改它们的表/列/定义。

问: Multi-Schema 似乎被设计为每个租户的表略有不同——我不想要这个。是否有任何 RDBMS 允许我使用多模式多租户解决方案,其中表结构在所有租户之间共享?

PS我所说的多是指超多(10.000+租户)。

4

4 回答 4

107

然而,当然也有一些公司担心他们的数据可能会受到损害,因此我们正在评估其他解决方案。

这是不幸的,因为客户有时会误以为只有物理隔离才能提供足够的安全性。

有一篇有趣的 MSDN 文章,标题为Multi-Tenant Data Architecture,您可能想查看它。这就是作者如何解决对共享方法的误解:

一个常见的误解认为只有物理隔离才能提供适当的安全级别。事实上,使用共享方法存储的数据也可以提供强大的数据安全性,但需要使用更复杂的设计模式。

至于技术和业务方面的考虑,本文简要分析了某种方法可能比另一种更合适的地方:

您期望服务的租户的数量、性质和需求都会以不同的方式影响您的数据架构决策。以下一些问题可能会使您偏向于更加孤立的方法,而其他问题可能会使您偏向于更加共享的方法。

  • 您预计有多少潜在租户?您可能无法通过权威估计预期用途,但请从数量级的角度考虑:您是否正在为数百名租户构建应用程序?数千?成千上万?更多的?您期望的租户群越大,您​​就越有可能考虑采用更共享的方法。

  • 您预计平均租户的数据占用多少存储空间?如果您希望部分或所有租户存储大量数据,那么分离数据库方法可能是最好的。(事实上​​,数据存储要求可能会迫使您采用独立数据库模型。如果是这样,那么从一开始就以这种方式设计应用程序要比以后转向独立数据库方法容易得多。)

  • 您希望平均租户支持多少并发最终用户?数字越大,越适合采用更孤立的方法来满足最终用户的要求。

  • 您是否希望提供任何按租户的增值服务,例如按租户的备份和恢复功能?通过更孤立的方法更容易提供此类服务。


更新:进一步更新预期的租户数量。

对于大多数情况(如果不是所有情况),预期的租户数量(10k)应该排除多数据库方法。我认为您不会喜欢维护 10,000 个数据库实例并每天必须创建数百个新实例的想法。

仅从该参数来看,共享数据库、单一模式方法似乎是最合适的。您将为每个租户存储大约 50Mb,并且每个租户都没有附加组件,这一事实使这种方法更加合适。

上面引用的 MSDN 文章提到了解决共享数据库方法的安全考虑的三种安全模式:

当您对应用程序的数据安全措施充满信心时,您将能够为您的客户提供提供强大数据安全保证的服务级别协议。在您的 SLA 中,除了保证之外,您还可以描述您将采取的措施以确保数据不被泄露。

更新 2:显然微软的人移动/制作了一篇关于这个主题的新文章,原来的链接已经消失,这是新的:多租户 SaaS 数据库租赁模式(感谢 Shai Kerer)

于 2010-02-06T12:13:05.560 回答
23

我的经验(尽管是 SQL Server)是多数据库是要走的路,每个客户端都有自己的数据库。因此,尽管我没有 mySQL 或 Ruby On Rails 经验,但我希望我的输入可能会增加一些价值。

原因包括:

  1. 数据安全/灾难恢复。每家公司的数据都与其他公司的数据完全分开存储,从而降低了数据被泄露的风险(想想如果您引入了一个代码错误,这意味着在不应该的情况下错误地查看了其他客户数据),最大限度地减少了一个客户的潜在损失特定的数据库被损坏等。对客户端的感知安全性好处甚至更大(增加了额外的副作用!)
  2. 可扩展性。本质上,您将数据分区以实现更大的可扩展性 - 例如,数据库可以放在不同的磁盘上,您可以使多个数据库服务器联机并更容易移动数据库以分散负载。
  3. 性能调优。假设您有一个非常大的客户和一个非常小的客户。使用模式、数据量等可能会有很大差异。如果需要,您可以更轻松地为每个客户端进行调整/优化。

我希望这确实提供了一些有用的输入!还有更多的原因,但我的大脑一片空白。如果它重新启动,我会更新:)

编辑:
自从我发布了这个答案,现在很明显我们正在谈论 10,000 多个租户。我的经验是使用数百个大型数据库 - 我认为 10,000 个单独的数据库对于您的场景来说不太容易管理,所以我现在不赞成在您的场景中使用多数据库方法。尤其是现在很明显,您正在为每个租户谈论小数据量!

无论如何都保留我的答案,因为它可能对类似船上的其他人有用(租户较少)

于 2010-02-06T12:38:30.953 回答
23

以下是 Salesforce.com 上关于他们如何实施多租户的白皮书的链接:

http://www.developerforce.com/media/ForcedotcomBookLibrary/Force.com_Multitenancy_WP_101508.pdf

他们有 1 个带有 500 个字符串列的大表(Value0、Value1、... Value500)。日期和数字以字符串的形式存储,以便它们可以在数据库级别转换为它们的本机类型。有一些元数据表定义了每个租户可以是唯一的数据模型的形状。还有用于索引、关系、唯一值等的附加表。

为什么麻烦?

每个租户都可以在运行时自定义他们自己的数据模式,而无需在数据库级别进行更改(更改表等)。这绝对是做这样的事情的艰难方法,但非常灵活。

于 2010-09-21T15:58:44.903 回答
13

正如您提到的,每个租户一个数据库是一种选择,并且确实有一些更大的权衡。它可以在较小的规模上很好地工作,例如个位数或低 10 的租户,但除此之外,它变得更难管理。既只是迁移,也只是保持数据库的正常运行。

每个模式模型不仅对每个模式的唯一模式有用,尽管仍然在所有租户之间运行迁移变得困难,并且在 1000 个模式下 Postgres 可能会开始遇到麻烦。

一种更具可扩展性的方法绝对是让租户随机分布,存储在同一个数据库中,但跨不同的逻辑分片(或)。根据您的语言,有许多库可以提供帮助。如果您使用的是 Rails,则有一个库来执行租户acts_as_tenant,它有助于确保您的租户查询仅拉回该数据。还有一个 gem apartment- 尽管它使用模式模型,但它确实有助于跨所有模式的迁移。如果您使用的是 Django,则有一个数字,但其中一个更受欢迎的似乎是跨模式。所有这些都有助于在应用程序级别上提供更多帮助。如果您直接在数据库级别寻找更多内容,Citus专注于为多租户使用 Postgres 开箱即用。

于 2016-09-07T21:07:23.907 回答