我们目前拥有一个系统,每个用户都可以获得一个数据库。我们现在转向一个数据库多租户架构,因此一个数据库可以容纳许多客户。
几个问题:
是否存在多租户转换工具?或者只是创建Tenant
表并在每个其他表中添加TenantID
的过程?
是否有一种简单的方法来实现多租户而无需重构与数据库通信的代码?
我们有一个Odata.svc
可以完成与数据库的对话(我们的前端客户端范围从.net前端到iOS设备)。我读了一些关于使用Federation来对tenantID
谓词执行过滤的内容,因此根本不需要更改代码。这可能吗?
是否建议限制数据库中应有多少租户?
我正在收集这是一个愚蠢的问题(一段字符串有多长)。我们很可能会在Azure上托管最终解决方案。
期待任何人可以给我的建议。我们正在对我们的流程进行根本性的改变,所以我希望在我们处理它之前能够掌握它。
答案 0 :(得分:3)
<强>自动化吗
理论上,应该可以制作一种工具,使其更容易执行这项艰巨的操作(从单租户到多租户)。但是,鉴于此类产品的受众人数有限,我不认为这样的工具存在。如果一个浮出水面,这将是非常好的。
关于手动转化的想法
首先设计一个新的多租户数据库架构。 (这意味着将所有单租户数据库模式与您可能拥有的任何共享模式合并。)我希望将其设置为没有遗留考虑因素。
您显然需要一个Tenant
表,您需要使用Tenant_id
列的许多现有单租户表引用该表。例如,具有用户的表将要求此用户唯一地将用户与租户相关联。
如果是一个简单的Products
表(以Product_id
为主键),则应该可以添加Tenant_id
列,从而产生一个带有复合键的表({ {1}}和Tenant_id
)。但是,如果您从头开始编写应用程序,我相信没有租户引用的Product_id
表是正确的方法。这也允许租户共享产品,而不是添加重复项。由于一个租户可能拥有Product
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是其可扩展性。今天,您可以根据需要轻松创建数据库服务器集群或使用基于云的解决方案无缝地添加更多硬件电源。
感兴趣的链接
答案 1 :(得分:2)
说实话,根据我的经验,你不能自动化。您正在将非常重要的数据从基础架构移动到数据模型中。每个查询都是在租户已经建立的假设下编写的。每个查询&amp;因此,SP将更改为引用回租户表并进行参数化。
如果您只是将tenantID添加到每个表中,请在Q1中询问。这将是一种方法,但不是我提倡的方法。它会导致您对数据不正确(没有强制执行,即子项与父项具有相同的tenantID,甚至它们都是相同的!)您需要确定添加租户表,然后仔细选择需要的表参考它。它不会是每个人。有些人会要求它,有些人可能会出于性能原因选择把它放在那里。如果您决定后者,您无疑需要额外的检查机制来保持您的数据有意义。
如果您在Oracle中,您可能能够做的就是将每个表重新编写到一个视图中(仍然执行上述所有操作)然后将tenantID填充到会话中并执行一些细粒度访问它以隐藏客户端的大部分细节。虽然很难做好,但我不确定SQL Server的等价物是什么。值得一些研究。
合并数据库背后的原因是什么?你需要一些跨数据库报告吗?否则,单租户有许多优点(多次升级和停机时间表,性能可以更好,具体取决于您的规范化程度,单租户数据提取/报告的简易性,当您失去租户时易于移除)。云解决方案&amp;单个租户可能会对您有利。