为EACH客户端使用单个数据库有什么好处?

时间:2008-08-16 20:39:26

标签: database database-design multi-tenant

在为多个客户端设计的以数据库为中心的应用程序中,我一直认为为所有客户端使用单个数据库“更好” - 将记录与适当的索引和密钥相关联。在收听Stack Overflow播客时,我听到Joel提到FogBugz每个客户端使用一个数据库(所以如果有1000个客户端,则会有1000个数据库)。使用这种架构有什么好处?

据我所知,对于某些项目,客户需要直接访问所有数据 - 在这样的应用程序中,很明显每个客户端都需要自己的数据库。但是,对于客户端不需要直接访问数据库的项目,每个客户端使用一个数据库有什么好处吗?似乎在灵活性方面,使用具有表的单个副本的单个数据库要简单得多。添加新功能更容易,创建报告更容易,而且管理起来更容易。

我对“所有客户的一个数据库”方法非常有信心,直到我听到Joel(一位经验丰富的开发人员)提到他的软件采用了不同的方法 - 我对他的决定感到有些困惑...... / p>

我听说人们引用数据库会因为大量记录而变慢,但任何具有一些优点的关系数据库都不会出现这个问题 - 特别是如果使用了正确的索引和密钥。

非常感谢任何输入!

10 个答案:

答案 0 :(得分:46)

假设将所有客户端存储在一个数据库中没有缩放惩罚;对于大多数人来说,以及配置良好的数据库/查询,这些日子都是相当正确的。如果你不是这些人中的一个,那么单个数据库的好处是显而易见的。

在这种情况下,好处来自每个客户的封装。从代码的角度来看,每个客户端都是孤立存在的 - 没有可能的情况,数据库更新可能会覆盖,损坏,检索或更改属于另一个客户端的数据。这也简化了模型,因为您不需要考虑记录可能属于另一个客户端的事实。

您还可以获得可分离性的好处 - 抽取与给定客户端关联的数据并将它们移动到不同的服务器是微不足道的。或者在使用内置数据库机制调用“我们删除了一些关键数据!”时恢复该客户端的备份。

您可以轻松获得免费的服务器移动性 - 如果您超越一个数据库服务器,则可以在另一台服务器上托管新客户端。如果它们都在一个数据库中,您需要获得更强大的硬件,或者在多台机器上运行数据库。

您可以轻松进行版本控制 - 如果一个客户端希望保留软件版本1.0,而另一个客户端想要2.0,其中1.0和2.0使用不同的数据库模式,则没有问题 - 您可以迁移一个而无需将其从一个数据库中取出

我想,我可以想到几十个。但总而言之,关键概念是“简单”。该产品管理一个客户端,因此管理一个数据库。 “数据库还包含其他客户端”问题从未出现任何复杂性。它适合用户的心理模型,它们独自存在。能够一次轻松地对所有客户进行简单报告的优势很少 - 您希望报告整个世界的频率,而不仅仅是一个客户?

答案 1 :(得分:13)

这是我以前见过的一种方法:

  • 每个客户都有一个存储在主客户数据库中的唯一连接字符串。
  • 数据库的设计使得所有内容都按CustomerID进行细分,即使数据库中只有一个客户也是如此。
  • 创建脚本以在需要时将所有客户数据迁移到新数据库,然后只需要更新该客户的连接字符串以指向新位置。

这允许首先使用单个数据库,然后在您拥有大量客户端后轻松细分,或者更常见的是当您有几个客户过度使用该系统时。

我发现当所有数据都在同一个数据库中时,恢复特定客户数据非常困难,但管理升级要简单得多。

当每个客户使用一个数据库时,会遇到一个巨大的问题,即让所有客户都在相同的架构版本上运行,甚至不考虑在一大堆客户特定数据库上的备份作业。自然地恢复数据更容易,但是如果确保不永久删除记录(只标记已删除的标记或移动到存档表),那么您首先需要更少的数据库恢复。

答案 2 :(得分:11)

保持简单。您可以确定您的客户只看到他们的数据。记录较少的客户不必支付与数据库中可能存在的数十万条记录竞争的惩罚,而不是他们的记录。我不关心所有内容的索引和优化程度,会有一些查询确定他们必须扫描每条记录。

答案 3 :(得分:10)

那么,如果您的某个客户因为某些拙劣的导入工作或类似问题而告诉您恢复到其早期版本的数据,该怎么办?想象一下,如果您告诉他们“您不能这样做,因为您的数据在我们所有客户之间共享”或“抱歉,但由于客户X要求恢复数据库而导致您的更改丢失”,您的客户会有何感受。

答案 4 :(得分:9)

至于一次升级1000个数据库服务器的痛苦,一些相当简单的自动化应该照顾它。只要每个数据库都维护相同的模式,那么它就不会成为问题。我们还使用每个客户端的数据库方法,它对我们很有用。

这是一篇关于这个确切主题的文章(是的,它是MSDN,但它是一篇与技术无关的文章):http://msdn.microsoft.com/en-us/library/aa479086.aspx

此处与您的数据模型相关的多租户的另一个讨论:http://www.ayende.com/Blog/archive/2008/08/07/Multi-Tenancy--The-Physical-Data-Model.aspx

答案 5 :(得分:6)

可扩展性。安全。我们公司每个客户的方法也使用1个DB。它还使代码更易于维护。

答案 6 :(得分:4)

我只是添加了这个答案,在这里包含多租户这个词。我正在搜索这个,使用“multitenant”作为查询,而这个没有出现。

答案 7 :(得分:3)

感谢您的投入 - 所有优秀且非常有效的观点。我想我更关注升级灵活性。如果您需要修改架构以添加新功能(比如Web应用程序)或增强现有功能,则可以在单个数据库中轻松完成。如果必须在1000个单独的数据库中复制此更改,则错误的可能性会增加。如果操作失败怎么办?升级每个客户需要多长时间?

如果保留了适当的备份(或者您的数据库是在数据从未实际覆盖的情况下构建的),则为特定客户端恢复数据非常简单。

代码的简单性虽然重要,但实际上并不是非常复杂。根据所使用的语言和方法,创建仅代表特定客户端(存储特定客户端ID)的对象很简单,而项目的其余部分只需针对单个对象进行编码(有点像单个客户端) )。

可扩展性是需要考虑的事项 - 您可以轻松获取单个隔离数据库并将其移至不同的物理服务器;然而,将服务器集群在一起变得越来越容易 - 即使没有集群,似乎只需要将每个客户端指向托管通用数据库的数据库SERVER(因此您可能有两个或三个数据库服务器托管)例如,每个只有一个数据库。这种方法使升级过程仅限于三个数据库。

答案 8 :(得分:2)

在医疗保健等受监管的行业中,每个客户可能需要一个数据库,甚至可能是单独的数据库服务器。

升级时更新多个数据库的简单答案是将升级作为事务进行升级,并在必要时进行升级之前拍摄快照。如果您正在运行您的操作,那么您应该能够将升级应用于任意数量的数据库。

群集并不是索引和全表扫描问题的真正解决方案。如果移动到群集,则几乎没有变化。如果您有许多较小的数据库要分布在多台计算机上,则可以在没有群集的情况下更便宜地执行此操作。可靠性和可用性是考虑因素,但可以通过其他方式处理(有些人仍然需要群集,但大部分人可能不需要)。

我有兴趣听一下你的更多上下文,因为集群不是一个简单的主题,在RDBMS世界中实现起来很昂贵。在非关系世界Google Bigtable等中有很多关于聚类的讨论/虚张声势,但他们正在解决一组不同的问题,并且丢失了一些RDBMS的有用功能。

答案 9 :(得分:0)

“数据库”有几个含义

  • 硬件盒
  • 正在运行的软件(例如“the oracle”)
  • 特定的数据文件集
  • 特定登录或架构

Joel可能意味着较低层之一。在这种情况下,只需要进行软件配置管理......例如,您不必修补1000个软件服务器来修复安全漏洞。

我认为这是一个好主意,因此软件错误不会泄露客户端的信息。想象一下这个案例中有一个错误的where子句,它向我展示了你的客户数据以及我自己的客户数据。