可以在一台SQL服务器上放置的数据库数量有限制吗?


43

我正在建立一个SaaS系统,我们打算在该系统中为每个客户提供他们自己的数据库。该系统已经设置好,因此如果负载太大,我们可以轻松地扩展到其他服务器。我们希望拥有成千上万的客户。

问题

  • 在一个SQL Server上可以/应该具有的微数据库数量是否有实际限制?
  • 它会影响服务器的性能吗?
  • 拥有10,000个每个100 MB的数据库或一个1 TB的数据库是否更好?

附加信息

当我说“微数据库”时,我并不是真的意思是“微”。我只是说我们的目标是成千上万的客户,因此每个单独的数据库仅占总数据存储量的千分之一或更少。实际上,每个数据库的容量大约为100MB,这取决于它获得的使用量。

使用10,000个数据库的主要原因是可伸缩性。事实是,系统的V1有一个数据库,当数据库承受负载时,我们经历了一些不舒服的时刻。

所有这些都使CPU,内存,I / O紧张。即使我们解决了这些问题,他们也使我们意识到,即使在世界上索引最佳的情况下,如果我们如希望的那样成功,我们也无法将所有数据都放在一个巨大的鸿沟中的数据库。因此,对于V2,我们正在分片,以便可以在多个数据库服务器之间分配负载。

去年,我花了很多时间来开发这种分片解决方案。每个服务器一个许可证,但是由于我们在Azure上使用VM,因此无论如何都要照顾好它。之所以出现这个问题,是因为以前我们只向大型机构提供服务,并且自己建立每个机构。我们的下一个业务是自助服务模型,任何使用浏览器的人都可以注册并创建自己的数据库。与大型机构相比,他们的数据库将更小,数量更多。

我们尝试了Azure SQL数据库弹性池。性能非常令人失望,因此我们切换回常规VM。

Answers:


80

我曾在单个实例上使用8至1万个数据库的SQL Server上工作。不好看

重新启动服务器可能需要一个小时或更长时间。考虑一下10,000个数据库的恢复过程。

您不能使用SQL Server Management Studio在对象资源管理器中可靠地定位数据库。

备份是一场噩梦,因为要使备份值得,您需要拥有一个可行的灾难恢复解决方案。希望您的团队擅长编写所有脚本。

你开始做这样的事情命名数据库与数字一样M01022,和T9945。试图确保您在正确的数据库中工作,例如M001022而不是M01022,可能会令人发疯。

为那么多数据库分配内存可能会很麻烦。SQL Server最终需要进行大量的I / O操作,这实际上是对性能的拖累。考虑一个在10,000个公司的4个表中记录碳使用详细信息的系统。如果在一个数据库中执行此操作,则只需要4个表;如果在10,000个数据库中执行此操作,突然间您将需要40,000个表。处理该数量的表在内存中的开销是巨大的。如果有10,000个数据库正在使用,则您针对这些表设计的任何查询都将在计划缓存中至少需要10,000个计划。

上面的列表只是在以这种规模进行操作时需要计划的一小部分问题。

您可能会遇到诸如SQL Server服务之类的问题,并且启动时间很长,这可能导致服务控制器错误。您可以自己增加服务启动时间,创建以下注册表项:

子项:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control
名称:ServicesPipeTimeout
类型:REG_DWORD
数据:服务启动期间发生超时之前的毫秒数

例如,要在服务超时之前等待600秒(10分钟),请键入600000。


自编写答案以来,我已经意识到问题在谈论Azure。也许在SQL数据库上执行此操作不是那么麻烦。也许这更成问题。就个人而言,我可能会设计一个使用单个数据库的系统,也许是在多个服务器之间垂直分片,但每个客户一个数据库肯定不是。


3
好东西。发布者可能会考虑使用多个数据库的方法,但是每个数据库使用多个客户,这样他们可以限制数据库的数量,但是仍然可以扩展到多个服务器。
托尼·欣克尔

5
我目前管理一个数据库计数高到4位的实例,几乎可以回显所有这些信息。当以这种规模进行操作时出现的另一个问题是无法长时间缓存执行计划。结果是大量的CPU烧录重新编译查询计划。
alroc

19

因此,这两种方法都有优点和缺点。在不了解您想要提供的应用程序或服务的更多信息的情况下,我将无法给出确切的答案,但我会就此事提出一些想法。

我的理由是为什么您应该对所有客户端使用1个数据库。

优点

  • 易于维护。拥有一个数据库意味着您只需在一个位置上执行维护任务,而无需在多个位置上执行。想象一下处理1000个不同数据库进行备份的噩梦。如何更新1000个数据库的统计信息或重建索引或DBCC CHECKDB

  • 部署代码。假设您在应用程序代码或报表中的存储过程有问题。您需要进行快速更改...现在,您必须将该更改部署到1000多个DB。不,谢谢,我宁愿不要。

  • 易见性。只需想象一下SSMS试图打开1000多个DB (抖动)。实际上,该问题将变得毫无用处,并且仅花费很长时间才能打开并呈现SSMS。请记住,那就是您能够提出一个体面的命名约定。

缺点

  • 安全。如果您将其他客户数据作为独立的数据库,则可以防止人们查看其他客户数据。但是,您可以执行一些非常简单的操作来防止这种情况的发生。

  • 性能。可以争辩说,每个客户将数据库限制为一个数据库意味着SQL Server将不得不扫描较少的数据以获取您要查询的信息。但是,如果使用适当的数据结构和良好的索引编制(以及可能的分区),则可以将其作为一个问题而彻底消除,如果仔细进行的话。我建议给包含客户特定数据的每个表某种形式的引导,CompanyID以减少开销。

最终,我认为最好的选择是为您的应用程序使用一个数据库,并在数据库内部拆分客户数据。与管理1000多个数据库的噩梦相比,它给您带来的麻烦将不算什么。


17

SQL Server的最大容量规范指出最大限制为32,767。

至于它是否会影响性能,答案是肯定的,但是它会影响性能的方式以及它是否是实质性的,将取决于众多因素。

除非有充分的理由将其拆分为10,000个数据库,否则我会选择一个数据库。一个备份还是10,000个备份?一份完整性检查,还是一万张?使用10,000个小型数据库可能有充分的理由,但是您没有给出足够的详细信息来确定这一点。您提出的问题范围很广,并且没有足够的信息让任何人知道最佳答案是什么。


7

您在这里谈论的是多租户多实例架构。我只是提出这些术语,因为您没有在问题中使用它们,但这就是您正在讨论的术语,如果您将“多租户体系结构”插入Google,则会发现大量资源和讨论内容关于它,整本书都写在上面。

这里有一些有关SQL Server的很好的资源:

https://msdn.microsoft.com/zh-CN/library/ff966499.aspx

https://docs.microsoft.com/zh-cn/azure/sql-database/sql-database-design-patterns-multi-tenancy-saas-applications

我会有其他答案,因为我会强烈倾向于默认多租户,除非您有令人信服的理由支持多实例。

您无需拆分成成千上万的个人客户端数据库即可进行扩展,还有许多其他方式可以这样做。像集群,复制,分片,分区等。不要重新发明轮子。没有内在的含义可以说明您需要在单个客户级别上手动拆分自己,并且确实这样做可能会大大增加添加每个新客户的成本。

您在谈论“数百万”的客户,想到任何大型的基于云的软件即服务,Gmail,无论如何,您几乎不会认为他们为每次新注册都创建了一个全新的数据库,对吗?

您确实有某些理由希望这样做,例如,如果您要向客户销售产品,而该产品必须在自己的基础架构上内部托管。但是作为一般的SAAS规则,精简默认为多租户架构。


7

对于单一数据库建议,我可以看到的缺点之一是回滚数据-如果每个租户设置都有一个数据库,则可以独立地还原每个客户端的数据(并还原到特定的时间点)。如果它们全部都在一个数据库中,这将变得更加困难(并且更容易出错,因为可能需要通过INSERT / UPDATE / DELETE语句来完成)。


+1-这是每个租户拥有一个数据库的极少数极好的好处之一。
马克斯·弗农

6

感谢所有回答-非常感谢您给我的思考要点。我的总体感觉是,最好使用单个数据库,但是我想补充一些观点,以支持分片架构,并解决其他人提到的一些问题。

分片的动机

正如(更新的)问题中提到的,我们的目标是在全球范围内实现数百万用户的大规模销售。凭借世界上最好的硬件和索引,单个数据库服务器将不会承担任何负载,因此我们必须能够在多个服务器之间进行分配。而且,一旦您必须查找任何给定客户的数据在哪台服务器上,为他们提供专用数据库就无需做太多工作了,这在保持人员数据整齐隔离方面使事情变得更加简单。

对关注的回应

  • 重新启动服务器需要很长时间:是的,但是在正常操作中,我们不打算重新启动任何服务器。该系统最终必须全天候在线24/7,因此,如果我们要停机,则无论如何都必须对其进行计划。
  • 备份/灾难恢复:我们正在使用CloudBerry,它可以自动执行所有操作。没问题
  • 命名数据库/在SSMS中定位它们:命名约定很简单,仅基于客户名称即可。如果名称共享,请添加序列号。
  • 维护:如果每个数据库都像我想象的那么小,则无需手动重建索引。
  • 部署代码:我们使用实体框架,因此每一个架构更改都将自动发布到具有新版本的每个数据库中。但是,确实可以发现,如果我们发现生产中的性能问题可以通过简单的索引调整来解决,那么将其推出就不是那么容易了。另一方面,由于每个数据库都太小,因此生产分片上不太可能出现顶级性能问题。通用数据库仍然是单个数据库,这些问题不适用。

如果您认为我有任何遗漏,我们将很乐意在评论中回覆您!


3
如果您正在寻找24/7的正常运行时间,则需要研究如何对数据库进行集群。仅应用补丁程序将至少导致一些停机时间。不知道这如何适用于基于云的解决方案(例如Azure),我希望它能为您解决。
杰·泽洛斯

我相信,使用当今的数据库技术,几乎所有“分片”的理由都不再成立。我相信您要么会后悔,要么甚至可能不会意识到自己相对较差,因此不会因无知而后悔。我同意马克斯的回答,无法更好地解释它。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.