代码之家  ›  专栏  ›  技术社区  ›  Marcel Jackwerth

如何创建具有共享表结构的多租户数据库?

  •  113
  • Marcel Jackwerth  · 技术社区  · 14 年前

    我们的软件目前运行在mysql上。所有租户的数据都存储在同一个模式中。因为我们使用RubyonRails,所以可以很容易地确定哪些数据属于哪个租户。当然,也有一些公司担心他们的数据可能会受到损害,所以我们正在评估其他解决方案。

    到目前为止,我看到了三种选择:

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

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

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

    P.S.多的意思是超多的(10000多个租户)。

    4 回复  |  直到 7 年前
        1
  •  80
  •   gmslzr Daniel Vassallo    7 年前

    但是有一些公司 当然,他们害怕自己的数据 妥协,所以我们正在评估 其他解决方案。

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

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

    一个常见的误解认为 只有物理隔离才能提供 适当的安全级别。在 事实上,使用共享 这种方法还可以提供强有力的数据 安全,但需要使用更多 精致的设计图案。

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

    的数量、性质和需求 你希望为所有人服务的租户 您的数据架构决策 不同的方式。以下部分 问题可能使你倾向于 孤立的方法,而其他方法可能 倾向于更分享 方法。

    • 你预计有多少潜在的房客?你可能不在 几乎可以估计 有权威的预期用途,但 按数量级思考: 你是在申请 成百上千的房客?数以千计?经皮电刺激神经疗法 成千上万?更多?你越大 希望你的房客基础是 你更可能会考虑 更加共享的方法。

    • 您希望平均租户的数据占用多少存储空间? 如果您希望一些或所有租户 存储大量数据, 单独的数据库方法可能是 最好的。(事实上,数据存储 要求可能会迫使您采用 无论如何都要分离数据库模型。如果是这样, 它将更容易设计 应用程序从 开始而不是移动到 稍后单独的数据库方法。)

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

    • 您希望为每个租户提供增值服务吗? 按租户备份和恢复 能力?这样的服务更容易 通过更孤立的 方法。


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

    对于大多数情况(如果不是所有情况),预期的租户数量(10万)应该排除多数据库方法。我不认为你会想到维护10000个数据库实例,每天都要创建数百个新实例。

    仅从这个参数来看,它看起来像共享数据库,单模式方法是最合适的。您将只为每个租户存储大约50MB的内存,并且没有每个租户的附加组件,这使得这种方法更加合适。

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

    当您对应用程序的数据安全措施充满信心时,您将能够为客户提供 Service Level Agrement 这提供了强有力的数据安全保证。在您的SLA中,除了保证之外,您还可以描述将要采取的措施,以确保数据不会受到损害。

    更新2: 很明显,微软的人就这个问题发表了一篇新的文章,原来的链接消失了,这是新的: Multi-tenant SaaS database tenancy patterns (向谢克勒致敬)

        2
  •  15
  •   AdaTheDev    14 年前

    我的经验(尽管是SQL Server)是多数据库的发展方向,每个客户机都有自己的数据库。所以尽管我没有MySQL或RubyonRails的经验,但我希望我的输入能增加一些价值。

    原因包括:

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

    我希望这能提供一些有用的信息!有更多的原因,但我的头脑一片空白。如果它重新启动,我将更新:)

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

    把我的答案保持在这里,因为它可能对其他人在一艘类似的船上有一些用处(更少的租户)

        3
  •  15
  •   hjd    12 年前

    下面是Salesforce.com上关于如何实现多租户的白皮书的链接:

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

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

    为什么麻烦?

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

        4
  •  8
  •   CraigKerstiens    8 年前

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

    每个模式模型不仅对每个模式都有用,尽管仍然在所有租户之间运行迁移变得困难,而且在1000多个模式下,Postgres可能会开始出现问题。

    更可扩展的方法是让租户随机分布,存储在同一个数据库中,但跨不同的逻辑碎片(或 tables )根据您的语言,有许多库可以帮助您实现这一点。如果你用的是Rails,那就有一个图书馆来实施租赁。 acts_as_tenant ,它有助于确保您的租户查询只返回该数据。还有一块宝石 apartment -尽管它使用模式模型,但它确实有助于跨所有模式进行迁移。如果你用的是django,有一个数字,但其中一个更受欢迎的数字似乎是对的。 schemas . 所有这些在应用程序级别上都有更多的帮助。如果您要直接在数据库级别寻找更多信息, Citus 专注于为 multi-tenancy 与Postgres一起,更加开箱即用。