分片的陷阱是应用程序必须知道要查询哪个分片。通常,这是通过在客户端上分片来完成的。我将改编我的旧博客文章之一作为答案。
在为许多客户构建应用程序时,有两种常见的方法来设计数据库:
- 选项A:将所有客户端放在同一数据库中
- 选项2:为每个客户端建立一个数据库
将所有客户端放入同一数据库
很简单:只需在架构顶部添加一个Client表,添加一个ClientUsers表以确保人们只能看到他们自己的数据,然后就可以了。
这种方法的好处:
简化架构管理。开发人员部署新版本的应用程序时,只需在一个数据库中进行架构更改。不用担心不同的客户不同步或版本错误。
性能调整更容易。我们可以在一个地方检查索引的使用情况和统计信息,轻松实现改进,并立即在所有客户中看到效果。对于成百上千的数据库,即使最小的更改也可能难以协调。我们可以检查过程高速缓存的内容,并确定哪些查询或存储过程是整个应用程序中最密集的,但是如果每个客户端使用单独的数据库,则在不同执行计划中汇总查询使用的时间可能会更困难。
易于构建外部API。如果我们需要为外部人员授予对整个数据库的访问权限以构建产品,那么如果所有数据都在单个数据库中,则我们可以更轻松地进行操作。如果API必须处理来自多个服务器上多个数据库的数据分组,则它会增加开发和测试时间。(另一方面,“多台服务器”开始暗示对一个数据库到所有规则的所有场景的限制:一个数据库通常意味着我们所有的负载只会影响一个数据库服务器。)借助PowerBI,将每个人都放在一个数据库中将使连接管理变得更加容易。
轻松实现高可用性和灾难恢复。如果我们只需要担心一个数据库,那么管理数据库镜像,日志传送,复制和集群非常非常简单。我们可以快速构建基础设施。
将每个客户端放入自己的数据库或碎片中
您仍然需要一个客户端列表,但现在它成为一个目录-对于每个客户端,您还可以跟踪其所在的分片。启动时,您的应用程序查询此表并将其缓存在RAM中。当它需要客户端的数据时,它直接连接到该分片(数据库和服务器)。
这种方法的好处:
单客户端还原更容易。客户是不可靠的肉袋。(除了我,它们是可靠的肉袋。)他们有各种各样的“糟糕”时刻,他们想将所有数据恢复到某个时间点,如果数据混杂在一起,那将是后方的巨大痛苦。同一表中的其他客户端数据。在单客户端数据库场景中进行还原非常容易:只需还原客户端的数据库即可。没有人受到影响。
数据导出更容易。客户喜欢获得数据。他们希望安全地知道自己可以随时获取数据,避免了可怕的供应商锁定情况,并且希望自己进行报告。将每个客户端的数据隔离到自己的数据库中后,我们可以简单地给他们一个自己的数据库备份的副本。我们不必构建数据导出API。
简化多服务器可伸缩性。当我们的应用程序需要的功能超出我们从单个服务器获得的能力时,我们可以在多个服务器之间划分数据库。我们还可以在地理上分散负载,将服务器放置在亚洲或欧洲以更接近客户。
简化每个客户端的性能调整。如果某些客户使用不同的功能或报告,我们可以为那些客户建立一套专门的索引或索引视图,而无需增加每个人的数据量。诚然,这里存在一些风险–通过允许客户端之间的架构差异,我们使代码部署的风险有所提高,而性能管理也更加困难。
简化安全管理。只要我们已正确锁定每个数据库只有一个用户的安全性,我们就不必担心客户端X访问客户端Y的数据。但是,如果我们仅对所有人使用一个登录名,那么我们还没有真正解决这个问题。
维护窗口更简单。 在客户遍布全球的全球环境中,如果我们可以按组或区域进行维护,则使客户脱机进行维护更加容易。
哪一个适合您?
没有一个正确的选择:您必须了解您自己公司的优缺点。让我们以我的两个客户为例。
甲公司擅长硬件性能调整。他们确实非常擅长将硬件的最后性能发挥到极致,并且他们不介意在12-18个月的周期内更换其SQL Server硬件。(他们每4-6个月刷新一次Web服务器!)他们的致命弱点是极高的合规性和安全性要求。他们具有难以置信的审计需求,对他们而言,在单个服务器,单个数据库上实施防弹控制比在多个服务器上的数千个数据库中管理这些要求要容易得多。他们选择了一个数据库,一台服务器和许多客户端。
公司2擅长开发实践。对于他们来说,管理模式更改和跨数千个数据库的代码部署并不是问题。他们有世界各地的客户,他们正在全天候为这些客户处理信用卡交易。他们需要能够在地理上分散负载的能力,并且他们不想每隔12-18个月就更换一次服务器。他们为每个客户选择了一个数据库,随着他们开始为离岸客户在亚洲和欧洲部署SQL Server,它正在获得回报。