将单个客户端SQL Server数据库转换为单个数据库多租户

5
我们目前拥有一个系统,每个用户都有一个数据库。我们现在将转移到一个多租户模式,一个数据库可以容纳多个客户。
以下是一些问题:
1. 是否存在多租户转换工具?或者只需创建“租户”表并向其他表添加“租户ID”即可? 2. 是否有一种简单的方法来实现多租户而无需重构与数据库通信的代码?我们有一个“Odata.svc”,它完成了所有与数据库的通信(我们的前端客户端涵盖从.NET前端到iOS设备)。我了解了一些有关使用联邦进行过滤的信息,在“租户ID”谓词上执行,这样代码就不需要更改。这可行吗? 3. 是否有建议限制数据库中租户数量的最大值?
我知道第三个问题可能很愚蠢(就像问线有多长一样),我们很可能会在Azure上托管最终解决方案。
期待您能给我任何建议。我们正在对我们的流程进行基本更改,因此我希望在掌握之前就能掌握它。
2个回答

3

自动化?

理论上,应该可以制作一个工具,使得执行这项艰巨的操作(从单租户转变为多租户)变得更加容易。然而,考虑到此类产品的受众有限,我认为目前并没有这样的工具存在。如果有这样的工具出现,那将是非常好的。

手动转换的想法

首先设计一个新的多租户数据库模式。(这意味着将所有单租户数据库模式与可能拥有的任何共享模式合并在一起。)我想让它看起来就像没有遗留问题的设计一样。

显然,您需要一个Tenant表,许多现有的单租户表都需要使用Tenant_id列引用它。例如,一个用户表将需要这个列来唯一地将用户与租户关联起来。

在一个简单的Products表中(Product_id作为主键),可以添加Tenant_id列,得到一个具有组合键(Tenant_id和Product_id)的表。但如果你从头开始编写应用程序,我认为没有租户参考的Product表是正确的方式。这也使租户可以共享产品,而不是添加副本。由于一个租户可能拥有具有Product_id 1、2、3的产品,另一个租户可能拥有Product_id 1、2,因此您不能简单地合并表,因为您不能两次使用相同的ID - 您需要唯一的主键值。
解决此问题的一种方法是编写一个程序(使用Java或其他高级语言),将所有数据从租户数据库读入内存对象,然后将数据写入多租户模式。该过程重复执行下一个租户数据库等。这样,您将拥有Product_id值1、2、3、4、5。一种快速而简单的方法是给每个架构中的所有ID值添加一个数字,例如1000、2000等,并希望不发生冲突。

与数据库通信的代码

您需要重写大部分数据库查询以考虑数据库现在是多租户的事实。这是一项艰巨的任务,特别是考虑到引入一个错误可能会让一个租户操纵另一个租户的数据的影响。但是,有些技术可以使这项任务变得更加容易。例如,租户视图过滤器 可以大大减少所需的工作量。

租户数量限制

我从未见过建议在多租户结构中限制租户数量的建议。相反,多租户方法的优势 是其可扩展性。今天,您可以轻松创建数据库服务器集群或使用基于云的解决方案,根据需要无缝添加更多硬件资源。

相关链接


2
说实话,在我的经验中,你不能自动化这个过程。你正在将非常重要的数据从基础架构移动到数据模型中。每个查询都是在假设租户已经建立的前提下编写的。因此,每个查询和存储过程都将被更改以引用回您的租户表并进行参数化。
你在Q1中问,如果只是在每个表中添加tenantID,那会是一种方法,但不是我提倡的方法。这会让你面临着有错误的数据(没有强制执行子级具有与父级相同的tenantIDs,甚至也不需要它们都是相同的)。你需要确保添加一个Tenant表,然后仔细选择哪些表需要引用它。不是每个表都需要引用它,有些表需要它,有些你可能选择把它放在那里出于性能考虑。如果您决定采用后者,您无疑需要额外的检查机制来使您的数据有意义。
如果你使用Oracle,你可能可以将每个表重新结构为视图(仍然需要执行以上所有操作),然后将tenantID插入会话中,并对其进行精细的访问以将大部分详细信息从客户端隐藏起来。不过,这很难做到,并且我不确定SQL Server的相应功能是什么。值得一些研究。
合并数据库的原因是什么?你需要一些跨数据库的报告或其他东西吗?否则,单租户具有许多优点(升级和停机时间表多样,性能可以更好,具体取决于你使用了多少规范化的数据,易于提取/报告单租户数据,在失去一个租户时易于移除)。云解决方案和单租户在这里潜在地起到作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接