我们为房地产公司设计网站。网站仅用于显示信息,所有网站共享一个通用模板。我们为不同的客户提供大约 150 个网站。一些第三方数据提供商每小时向我们提供有关网站上每个房源的所有更新。每个客户的更新发生在不同的时间。平均每个网站有 1000 个房源。每次每小时更新时,80% 的数据都会更改或更新。
目前我们在 SQL Server 2008 中有一个数据库,用于所有客户(最初设计用于满足 10-20 个网站的需求)。数据库中的表由所有人共享。问题是,每当发生更新时,它也会减慢与更新完全无关的其他客户网站的速度。此外,删除客户数据也会减慢所有网站的速度。
我计划通过为每个客户创建单独的架构来重塑数据库,但我不确定这是否是解决问题的最佳方法。拥有单独的数据库会给维护(备份、镜像等)带来很多问题。有人能建议我一种更好的方法来处理这个问题吗?我不确定如果我为每个客户创建单独的架构并将他们的表与其他表隔离开来,这会如何影响性能。或者有更好的解决方案吗?
答案1
我个人更喜欢使用多个数据库,因为它允许您通过各种 DMV 查看哪些数据库使用最多的 IO 和 RAM - 并且允许您轻松地将最大的数据库迁移到其他地方。此外,还有一个安全隔离,这总是让客户感到放心。
Brent Ozar 在最近的一篇博客文章中讨论了这个问题 - 绝对值得一读,因为他写得很好: http://www.brentozar.com/archive/2011/06/how-design-multiclient-databases/
答案2
尽管我可能建议每个客户都使用一个数据库,但如果您想要坚持使用一个数据库,那么看起来模式会适合您的要求。
但是,除了为每个客户创建一个架构之外,我建议您还为每个客户创建一个文件组,然后将每个客户的所有数据库对象放入该文件组中。这样做有几个优点:
- 提高数据库可用性。如果某个客户的数据文件损坏,仍然可以使数据库的其余部分恢复在线。即使在进行其他交易时,也可以从备份中恢复损坏的数据文件。
- (可能)性能更好。随着系统的增长,您可以将文件组放置到不同的存储设备上并分散 I/O(当然,您可以对一个文件组和多个文件执行类似操作,但这将允许您按客户拆分 IO)。
- 备份方便。数据库备份可以在文件组级别进行,让您可以更灵活地决定何时备份每个客户的表。
- 更好的恢复粒度。与 #1 类似,从头恢复数据库时,一旦主文件组在线,您就可以开始单独恢复文件组,从最重要的客户开始。由于后续恢复不会对已恢复的文件组产生任何影响,因此您可以逐个恢复数据库,而不是一蹴而就。这称为在线逐段恢复并且是企业版独有的功能(尽管在标准版中也可以做类似的事情,但它需要数据库处于离线状态)。
我相信您可以拥有的最大文件组数量是 32,000 左右,因此这种策略应该持续到您真正需要考虑拆分成不同的数据库为止。
欲了解更多信息,我推荐书籍在线文章'文件和文件组体系结构' 以及有关部分数据库可用性的 SQLCAT 白皮书:http://sqlcat.com/sqlcat/b/whitepapers/archive/2007/11/21/partial-database-availability.aspx
答案3
如果所有客户共享相同的数据库,并且所有网站都使用相同的模板,那么这更像是一个多租户cms,因此在这里拥有单一数据库实际上非常有意义。
我认为问题不在于一个客户的更新影响了所有其他客户,而在于更新和查询总体上只是速度较慢。假设硬件和负载不变,那么 150 个数据库的性能可能与单个数据库解决方案类似(在某些情况下可能更慢)
我假设您的主表是“列表”表,其中有大约 150*1000 个活动行(大概是 + 历史记录)。
无论如何,这并不是大量的数据,并且配置合理的机器应该不会出现问题。
我会确保将历史记录移至它们自己的表中。在读取查询中,我会添加“读取未提交的快照”
在更新中,有几种可能的解决方法 1. 使用合并而不是多个更新语句 2. 使用游标来防止锁定升级 3. 为更新的列表添加新记录,并且只更新旧记录上的“当前”位标志
考虑到这已是两年前的事情了,最终的解决方案是什么?
答案4
当我计划重组数据库基础架构时,我也问了自己同样的问题。这篇文章对我帮助很大。