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

Posted

技术标签:

【中文标题】将单客户端 SQL Server 数据库转换为单数据库多租户【英文标题】:Converting single client SQL Server database into single database multi tenant 【发布时间】:2011-12-06 15:35:41 【问题描述】:

我们目前有一个系统,每个用户都有一个数据库。我们现在正在转向一个数据库多租户模式,因此一个数据库可以容纳许多客户。

几个问题:

    是否存在多租户转换工具?还是只是创建一个Tenant 表并将TenantID 添加到每个其他表的过程?

    有没有一种简单的方法来实现多租户,而无需重构与数据库通信的代码?

    我们有一个Odata.svc,它可以与数据库进行所有对话(我们的前端客户端范围从 .net 前端到 ios 设备)。我阅读了一些关于使用 Federation 对 tenantID 谓词执行过滤的信息,因此根本不需要更改代码。这可能吗?

    对于数据库中的租户数量是否有建议限制?

我正在收集这是一个愚蠢的问题(一根绳子有多长)。我们很可能会在 Azure 上托管最终解决方案。

期待任何人能给我的任何建议。我们正在对我们的流程进行根本性的改变,所以我想在我们处于它之前就掌握它。

【问题讨论】:

【参考方案1】:

自动化?

理论上,应该可以制作一个工具,让更容易执行这个令人生畏的操作(从单租户到多租户)。但是,鉴于此类产品的受众有限,我认为这样的工具并不存在。要是能出现就太好了。

关于手动转换的想法

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

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

对于一个简单的Products 表(以Product_id 作为主键),应该可以添加一个Tenant_id 列,从而生成一个具有复合键的表(Tenant_idProduct_id )。但是,如果您从头开始编写应用程序,我相信没有租户引用的 Product 表是正确的方法。这还允许租户共享产品,而不是添加重复项。由于一个租户可能拥有Product_id 1,2,3 和另一个1,2 的产品,因此您不能简单地合并表,因为您不能两次使用相同的ID——您需要唯一的主键值。 解决此问题的一种方法是编写一个程序(使用 Java 或其他高级语言),将租户数据库中的所有数据读取到内存对象中,然后将数据写入多租户模式。对下一个租户数据库重复该过程,依此类推。这样你就可以得到Product_id 的值 1,2,3,4,5。一种快速而简单的方法是向每个模式中的所有 ID 值添加一个数字,例如 1,000、2,000 等等,然后简单地交叉手指以免发生冲突。

与数据库通信的代码

您将需要重写大多数数据库查询,以说明数据库现在是多租户的。这是一项艰巨的任务,特别是考虑到引入一个让一个租户摆弄另一个租户数据的错误的影响。然而,一些技术可以使这项任务更容易。例如,Tenant View Filter 可以大大减少所需的工作量。

租户数量限制

我从未见过限制多租户结构中租户数量的建议。相反,strength of the multi-tenant approach 是它的可扩展性。如今,您可以根据需要轻松创建数据库服务器集群或使用基于云的解决方案无缝添加更多硬件功能。

感兴趣的链接

Converting Single-Tenant to Multi-Tenant Apps Multi-Tenant Data Architecture

【讨论】:

【参考方案2】:

老实说,根据我的经验,您无法自动执行此操作。您正在将非常重要的数据从您的基础设施转移到您的数据模型中。每个查询都是在假设租户已经建立的情况下编写的。因此,每个查询和 SP 都将更改为引用回您的租户表并进行参数化。

您在 Q1 中询问是否只是将tenantID 添加到每个表中。那将是一种方法,但不是我提倡的方法。它会导致您对不正确的数据敞开心扉(没有强制孩子与父母拥有相同的tenantID,甚至它们都相同!)您需要确定添加一个租户表,然后仔细选择哪些表需要参考它。不会是每个人。有些人会需要它,有些人可能出于性能原因选择将它放在那里。如果您选择后者,您无疑将需要额外的检查机制来保持您的数据有意义。

如果您在 Oracle 中,您可能能够做的是将每个表重新加工成一个视图(仍然执行上述所有操作)然后将tenantID 填充到会话中并执行一些细粒度访问它以向客户隐藏大部分细节。虽然很难做好,我不确定 SQL Server equivilent 是什么。可能值得研究一下。

合并数据库的原因是什么?您需要一些跨数据库报告或其他东西吗?否则,单租户有很多优势(多个升级和停机计划,性能可能会更好,具体取决于您的 [去] 规范化程度,单租户数据提取/报告的便利性,失去租户时的轻松移除)。云解决方案和单一租户可能对您有利。

【讨论】:

以上是关于将单客户端 SQL Server 数据库转换为单数据库多租户的主要内容,如果未能解决你的问题,请参考以下文章

将单标签分类器转换为多标签分类器

将单元素数组的数组转换为一维数组

PHP将单维数组转换为嵌套数组

将单引号转换为字符串中的转义单引号

使用 JS 或 JQUERY 将单选按钮转换为只读(未禁用)

如何仅使用 javascript 将图像转换为字节数组以将图像存储在 sql server 上?