SQL Server - 强大的客户端数据保护(多租户)

4
我们正在考虑使用单个SQL Server数据库来存储多个客户的数据。相比“每个客户一个独立的数据库”的设置,我们觉得把所有数据放在一个数据库中会更容易管理。
我们最大的担忧是意外访问了错误的客户数据。如果我们意外地向另一个客户显示了某个客户的数据,那将非常糟糕。我们执行很多查询,担心出现这样的情况:“给我写一个查询,包含这个和那个,用于在15分钟后的会议上向客户展示。” 如果有人粗心地省略了筛选正确客户的WHERE子句,那么我们就会陷入严重的麻烦。是否有一种强大的SQL Server设置或设计模式,使从单个“全局”数据库中意外提取错误客户数据变得不可能(或至少非常困难)?
需要明确的是,这不是客户直接或通过应用程序使用的数据库(尚未)。我们正在谈论由我们几位程序员访问的数据库,并且我们担心自己会搞砸。

1
请先阅读这篇文章:http://msdn.microsoft.com/en-us/library/aa479086.aspx。 - Neil McGuigan
4个回答

2
至少,您应该将客户数据放在单独的架构中。在SQL Server中,架构是授权单位。只有被授权查看特定客户端的人员才能看到该客户端的数据。除了其他保护措施外,您还应该使用数据库的内置授权功能。
目前,听起来好像只有一小群人在访问所有人的数据。如果您成功了,未来可能需要更多的人。事实上,您可能会直接向某些客户提供数据访问权限。如果这是他们的数据,他们将希望在其上运行应用程序。
如果您计划扩展,我最好的建议是将每个客户的数据放在单独的数据库中。我会设计系统,使该数据库可以位于远程服务器上。如果需要与公共数据同步,则开发复制策略以移动该数据。
您可能认为让一个客户看到另一个客户的数据很糟糕。从业务角度来看,这是致命的 - 就像“公司倒闭,没有工作”的致命。您的客户可能比您更关心保密性。确保保护的架构将使他们感到更舒适。

是的,我们需要确保意外访问客户数据永远不会发生。我猜你不认为大量复杂数据库会变得难以管理?例如,如果需要更改任何数据库对象,您必须对所有数据库进行更改... - Tekito
嗯,大概这就是为什么客户们付费让你来维护的原因。你要做的就是开发一套简单的工具(最好是存储过程),以实现这个目标。你还需要一个发布流程,这其实是件好事。此外,你还要处理这样一种情况:当你发布新功能时,有个客户想继续使用旧系统。 - Gordon Linoff
将其标记为答案,因为我认为最终老板们会选择这个,尽管我最初是在寻求单数据库解决方案。 - Tekito
@Tekito...谢谢。写完这段话后,我意识到我真正想表达的观点。你对数据分离有一个严格的要求。你应该围绕这个要求设计系统,而不是做一些短期看起来方便的事情,然后让要求“适应”它。 - Gordon Linoff

2
多租户数据架构
这是我们的做法(不幸的是,我们使用的是MySQL):
  1. 在每个表中加入“租户”列
  2. 所有表都在一个模式中[1]
  3. 视图在另一个模式中(更容易进行安全性和命名)。视图不能包括租户列。视图根据当前用户基于租户进行WHERE操作
  4. 插入时触发器根据用户设置租户值
假设您的所有DDL都在源代码控制下的.sql文件中(应该是这样),那么拥有许多数据库或模式并不困难。
[1] 在MySQL中,模式称为“数据库”

1

您可以为每个表设置一个内联表值函数,该函数需要一个必需参数@customerID并将该特定表过滤到此客户的数据。如果整个应用程序仅使用这些TVP,则应用程序将通过构造安全

可能会有一些性能影响。确切的数字取决于模式和查询。但是它们可以为零,因为内联TVP与查询的其余部分一起进行内联和优化。


同意只使用 TVF 可以解决问题,但仍担心有程序员会忽略 TVF 并直接针对表编写查询。 - Tekito
您可以通过阅读代码轻松审核代码。您可以很容易地证明它的正确性。 - usr

0

您可以通过强制要求客户ID参数的存储过程来限制对数据的访问。 如果您允许IT构建视图,迟早会有人像您所说的那样忘记这个where子句。 但是为每个客户端创建一个模式,并使用已经预过滤的视图将使自助服务和额外的价值成为可能。


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