可以在一台 SQL Server 上放置的数据库数量是否有限制?

Sha*_*ehr 46 sql-server scalability azure-vm

我正在建立一个 SaaS 系统,我们计划在其中为每个客户提供自己的数据库。系统已经设置好,如果负载变得太大,我们可以轻松地扩展到其他服务器;我们希望拥有数千甚至数万名客户。

问题

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

附加信息

当我说“微数据库”时,我的意思并不是“微”;我的意思是我们的目标是成千上万的客户,所以每个单独的数据库只会占总数据存储量的千分之一或更少。实际上,每个数据库都在 100MB 左右,具体取决于它的使用量。

使用 10,000 个数据库的主要原因是为了可扩展性。事实上,系统的 V1 有一个数据库,当数据库在负载下紧张时,我们有一些不舒服的时刻。

它使 CPU、内存、I/O 变得紧张 - 以上所有。尽管我们解决了这些问题,但它们让我们意识到,在某些时候,即使使用世界上最好的索引,如果我们像我们希望的那样成功,我们根本无法将所有数据放在一个大喇叭中' 数据库。因此,对于 V2,我们进行了分片,因此我们可以在多个数据库服务器之间分配负载。

去年我一直在开发这个分片解决方案。每台服务器一个许可证,但无论如何,因为我们在 Azure 上使用虚拟机,所以已经解决了这个问题。现在出现这个问题的原因是,以前我们只向大型机构提供服务,并自己建立每个机构。我们的下一个业务是自助服务模式,任何拥有浏览器的人都可以注册并创建自己的数据库。他们的数据库将比大型机构小得多,数量也多得多。

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

Han*_*non 83

我曾在单个实例上处理过具有 8 到 10,000 个数据库的 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。也许在 Azure SQL 数据库上执行此操作没有那么大的问题;也许它更成问题。就我个人而言,我可能会设计一个使用单个数据库的系统,可能跨多个服务器垂直分片,但肯定不是每个客户一个数据库。

  • 我目前管理着一个数据库数量高达 4 位数的实例,并且几乎可以回应所有这些。以这种规模运行时出现的另一个问题是无法长时间缓存执行计划。结果是大量的 CPU 消耗重新编译查询计划。 (6认同)
  • 好东西。发帖人可能会考虑使用多个数据库的方法,但每个数据库有多个客户,这样他们就可以限制数据库的数量,但仍然能够扩展到多个服务器。 (3认同)

Zan*_*ane 19

所以这两种方法各有利弊。如果不了解有关您的应用程序或您希望提供的服务的更多信息,我将无法给出明确的答案,但我会就此提出一些想法。

我为什么应该为所有客户端使用 1 个数据库的案例。

优点

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

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

  • 容易的可见性。想象一下 SSMS 试图打开 1000 多个数据库(不寒而栗)。这实际上会使问题变得毫无用处,并且打开和呈现 SSMS 需要花费惊人的时间。请记住,前提是您能够提出一个合适的命名约定。

缺点

  • 安全。如果您将它们作为单独的数据库,则更容易防止人们查看其他客户数据。但是,您可以采取一些非常简单的措施来防止这种情况发生。

  • 表现。有人可能会争辩说,将每个客户限制为一个 DB 意味着 SQL 服务器将不得不扫描更少的数据来获取您正在查询的信息。但是,通过适当的数据结构和良好的索引(以及可能的分区),如果仔细完成,您可能可以将其作为一个问题一起消除。我建议为每个包含客户特定数据的表提供某种导致CompanyID减少开销的方法。

最终,我认为您最好的选择是为您的应用程序创建一个数据库,并在数据库本身内部拆分客户数据。与管理 1000 多个数据库的噩梦相比,它会给您带来的麻烦微不足道。


Ton*_*kle 17

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

至于会不会影响性能,答案是肯定的,但是会影响性能的方式,会不会很大,要看很多因素。

我会选择一个数据库,除非有充分的理由将其拆分为 10,000 个数据库。一个备份还是 10,000 个备份?一次完整性检查,还是 10,000 次?使用 10,000 个小数据库可能有充分的理由,但您没有提供足够的细节来确定这一点。您提出的问题非常广泛,根本没有足够的信息让任何人知道最佳答案是什么。


Iva*_*McA 8

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

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

https://msdn.microsoft.com/en-us/library/ff966499.aspx

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

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

您不需要拆分成数千个单独的客户端数据库来扩展,还有许多其他方法可以做到这一点,这可能是更可取的。像集群、复制、分片、分区等。不要重新发明轮子。没有什么内在说您需要在单个客户级别上自己手动拆分,并且确实这样做可能会显着增加添加每个新客户的成本。

你说的是“数百万”客户,想想任何大型基于云的软件即服务,Gmail,不管怎样,你几乎不认为他们为每个新注册创建一个全新的数据库,现在是吗?

您确实希望为此提供便利可能是有原因的,例如,如果您将产品销售给必须将产品托管在他们自己的基础架构上的客户。但作为一般的 SAAS 规则,将精益作为多租户架构的默认设置。


Dar*_*han 7

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


Sha*_*ehr 6

感谢所有回答的人 - 非常感谢您给我的思考点。我得到的总体感觉是单个数据库更可取,但我想添加一些支持分片架构的抵消点,并解决其他人提到的一些问题。

分片的动机

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

回应疑虑

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

如果您认为我遗漏了任何内容,我将很高兴在评论中收到您的回复!

  • 如果您正在考虑 24/7 的正常运行时间,那么您需要考虑对数据库进行集群。仅仅应用补丁至少会导致一些停机时间。不确定这如何适用于 Azure 等基于云的解决方案,我希望它为您服务。 (3认同)