在为多个客户端设计的以数据库为中心的应用程序中,我一直认为为所有客户端使用单个数据库“更好”——将记录与适当的索引和键相关联。在收听 Stack Overflow 播客时,我听到 Joel 提到 FogBugz 每个客户端使用一个数据库(因此,如果有 1000 个客户端,则将有 1000 个数据库)。使用这种架构有什么好处?
我知道对于某些项目,客户需要直接访问他们的所有数据——在这样的应用程序中,很明显每个客户都需要自己的数据库。但是,对于客户端不需要直接访问数据库的项目,每个客户端使用一个数据库有什么好处吗?似乎就灵活性而言,使用具有单个表副本的单个数据库要简单得多。添加新功能更容易,创建报告更容易,并且更易于管理。
在我听到 Joel(一位经验丰富的开发人员)提到他的软件使用不同的方法之前,我对“所有客户的一个数据库”方法非常有信心——我对他的决定有点困惑......
我听说有人提到数据库会因大量记录而变慢,但任何具有某些优点的关系数据库都不会出现这个问题——尤其是在使用适当的索引和键的情况下。
非常感谢任何输入!
假设将所有客户端存储在一个数据库中没有扩展损失;对于大多数人以及配置良好的数据库/查询而言,如今这将是相当真实的。如果您不是这些人中的一员,那么单个数据库的好处是显而易见的。
在这种情况下,好处来自对每个客户端的封装。从代码的角度来看,每个客户端都是孤立存在的——数据库更新不可能覆盖、破坏、检索或更改属于另一个客户端的数据。这也简化了模型,因为您无需考虑记录可能属于另一个客户端的事实。
您还可以获得可分离性的好处 - 提取与给定客户端关联的数据并将它们移动到不同的服务器是微不足道的。或者在调用“我们删除了一些关键数据!”时使用内置数据库机制恢复该客户端的备份。
您可以获得轻松且免费的服务器移动性——如果您超出了一台数据库服务器的规模,您可以在另一台服务器上托管新客户端。如果它们都在一个数据库中,您需要获得更强大的硬件,或者在多台机器上运行数据库。
您可以轻松进行版本控制 - 如果一个客户想要保留软件版本 1.0,而另一个客户想要 2.0,其中 1.0 和 2.0 使用不同的数据库模式,那么没有问题 - 您可以迁移一个,而无需将它们从一个数据库中拉出。
我猜我还能想出几十个。但总而言之,关键概念是“简单”。该产品管理一个客户端,因此管理一个数据库。 “但数据库还包含其他客户端”问题从来没有任何复杂性。它适合用户单独存在的心理模型。能够同时轻松报告所有客户的优势是微乎其微的 - 您希望多久报告一次全世界,而不仅仅是一个客户?
这是我以前见过的一种方法:
每个客户都有一个存储在主客户数据库中的唯一连接字符串。
该数据库的设计使得所有内容都按 CustomerID 进行分段,即使数据库中只有一个客户。
如果需要,将创建脚本以将所有客户数据迁移到新数据库,然后只需更新该客户的连接字符串以指向新位置。
这允许首先使用单个数据库,然后在您拥有大量客户后轻松进行分段,或者更常见的是当您有几个过度使用系统的客户时。
我发现当所有数据都在同一个数据库中时,恢复特定客户数据非常困难,但管理升级要简单得多。
当每个客户使用一个数据库时,您会遇到一个巨大的问题,即让所有客户都以相同的模式版本运行,这甚至不考虑在一大堆客户特定数据库上的备份作业。恢复数据自然更容易,但如果您确保不永久删除记录(只需用已删除标志标记或移动到存档表),那么您首先不需要数据库恢复。
保持简单。您可以确定您的客户只看到他们的数据。记录较少的客户不必支付与数十万条可能在数据库中但不是他们的记录竞争的惩罚。我不在乎所有内容的索引和优化程度如何,会有一些查询决定他们必须扫描每条记录。
那么,如果您的一位客户由于某些拙劣的导入工作或类似情况而告诉您恢复到他们的数据的早期版本怎么办?想象一下,如果您告诉客户“您不能这样做,因为您的数据在我们所有的客户之间共享”或“抱歉,您的更改丢失了,因为客户 X 要求恢复数据库”,您的客户会有什么感受。
至于一次升级 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
可扩展性。安全。我们公司也使用每个客户方法 1 DB。它还使代码更易于维护。
在医疗保健等受监管的行业中,可能需要每个客户一个数据库,甚至可能需要一个单独的数据库服务器。
升级时更新多个数据库的简单答案是将升级作为事务进行,并在必要时在升级之前拍摄快照。如果您的操作运行良好,那么您应该能够将升级应用到任意数量的数据库。
集群并不是真正解决索引和全表扫描问题的方法。如果你移动到一个集群,几乎没有什么变化。如果您有许多较小的数据库要分布在多台机器上,那么您可以在没有集群的情况下更便宜地做到这一点。可靠性和可用性是考虑因素,但可以通过其他方式处理(有些人仍然需要集群,但大多数人可能不需要)。
我有兴趣从您那里听到更多关于此的背景信息,因为集群不是一个简单的主题,并且在 RDBMS 世界中实施起来很昂贵。在非关系世界 Google Bigtable 等领域有很多关于集群的讨论/虚张声势,但他们正在解决一组不同的问题,并且失去了 RDBMS 的一些有用功能。
“数据库”有几种含义
硬件箱
正在运行的软件(例如“oracle”)
特定的数据文件集
特定的登录名或架构
乔尔很可能是指较低层之一。在这种情况下,这只是软件配置管理的问题……例如,您不必修补 1000 台软件服务器来修复安全漏洞。
我认为这是个好主意,这样软件错误就不会在客户端之间泄漏信息。想象一下带有错误 where 子句的情况,该子句向我显示了您的客户数据以及我自己的数据。