我记得在stackoverflow播客中,Fog Creek使用每个客户的数据库来存储Fogbugz。我认为这意味着Fogbugz On Demand服务器拥有数以万计的数据库。
我们才刚刚开始开发Web应用程序,并且有一个类似的问题要解决(很多拥有自己孤立数据的客户)。
使用每个客户的数据库我应该期待哪些问题?我该如何解决?
我的初步想法
每个客户的数据库优势

更简单的数据库架构
简单的备份-您可以依次备份每个客户而无需它确实会影响其他客户。
使导出给定客户数据的操作变得容易。
更好的缓存性能-对较活跃的表之一的写入只会影响执行该写入操作的单个客户。
更易于跨硬件扩展。例如,当我们需要从1台服务器迁移到2台服务器时,只需将一半的客户转移到新服务器上。

缺点

MySQL可以处理5,000个数据库吗?性能会不好吗?
对模式的更改可能很难在所有数据库中复制出来。我们真的真的需要为此制定一个自动化计划,例如对架构进行版本控制和一个脚本,该脚本可以理解如何将数据库从一个版本移植到另一个版本。
做所有客户共同的事情可能很尴尬。或不可能
与上面类似,但是我们想要对所有客户执行的任何分析都是不可能的。例如,我们应该如何跟踪所有客户的使用情况?


评论

请记住,“数据库”对不同的人来说意味着不同的事情。在Oracle的世界中,每个用户的数据库将是巨大的杀伤力。但是在MySQL中,“数据库”与“模式”是同义词。

我的意思是mysql。 USE CompanyData;

Microsoft有一篇有关多租户数据体系结构的详细文章。

我不会说对模型进行版本控制是不利的...更多的工作,但是总体上更好的

#1 楼

此解决方案称为多租户设计,其中每个租户(客户)都有自己的数据库。鉴于此,对于单一数据库的替代方法还有其他一些注意事项:


对于单个数据库,无论如何,每个人都必须使用相同的版本。无法升级某些客户,而不能升级其他客户。如果客户想要尚未准备好广泛发布的应用程序的修补程序,则可能会出现问题。
使用单个数据库,当您进行升级时,每个客户端都将关闭。如果出了问题,每个客户都会被搞砸。
使用单个数据库,限制资源就困难得多。也就是说,如果一个客户端要锤击数据库,则很难给他们更多的资源,而其他人则无法使用。
让用户托管自己的应用程序版本要困难得多。如果您要构建将由大型企业使用的解决方案,那么通常这是一个初学者。他们的IT部门希望完全控制对系统的访问。
扩展数据库而不是扩展数据库可能会更便宜。也就是说,与将客户扩展到更小,更便宜的数据库服务器相比,必须投资于更快的硬件来托管一个数据库以统治所有数据库,这可能会更加昂贵。我不能确切地说这个,因为它很大程度上取决于服务器软件。如果您坚持使用MySQL,那么这可能是正确的,因为许可成本可以忽略不计。但是,例如,如果您升级到SQL Server,则除非使用VPS环境以及扩展与扩展更改的成本效益,否则扩展成本会高得多。但是,我可以说,一旦数据库变得很大,管理就需要越来越高的专业水平。大型数据库需要使用多个文件组,并将某些索引推送到不同的主轴,以获得更好的性能。简而言之,它们很快就会变得复杂。

具有单独的数据库确实意味着您必须建立一种更新机制,以使数据库版本与应用程序/站点版本匹配。但是,单独的数据库确实提供了出色的数据隔离,并且IMO的托管成本较低。并非所有情况都适用。如果您的系统永远不会在托管范围之外托管,并且需要迅速扩大客户规模,并且希望所有用户使用相同版本的应用程序和数据库架构,那么肯定有一个数据库是更好的方法。 br />

评论


我同时使用共享数据库和多租户单独的数据库设置来运行Web服务。有时候两者都是正确的选择。在每个客户都有单独数据库的应用程序上,我遇到了完全相同的5个原因,这是该应用程序的正确选择。

–丹·格罗斯曼(Dan Grossman)
2011-2-5 20:06

亚马逊最近的Aurora无服务器云数据库据说可以在需要更高负载时自动调配更多资源,而且它们似乎鼓励单数据库设计。但是我不完全理解。我想我将使用单个数据库,但为每个用户使用单独的表。如果需要的话,这可能会更容易将它们拆分为单独的数据库,并使对所有用户数据的聚合查询更加容易。

–瓶Butkus
18/12/14在0:48

只是需要提防的事情:我将所有客户都放在一个db中,并使用db代码层来确保每个查询都包含特定于客户的条件。危险的一面是,当您必须走出数据库层以执行非常特定的操作时-例如可怕的大型复杂查询,其中数据可能会从意外地方泄漏出去。

– Enigma Plus
19-10-30在9:54

#2 楼

以我的经验,您不应该为每个客户创建一个数据库。让我举一个例子:

去年我使用了70个数据库(远少于5000个),每个数据库都具有相同的架构。从理论上讲,事情会按计划进行(如您在“优势”部分所述),但实际上并没有那么多。您有很多关于更新架构,用户支持,软件更新的问题。太糟糕了。

我们使用了Firebird,在产品交付后我被录用了,但这让我掌握了从不使用分离的数据库的知识。

我并不是说您无法实现目标,而是说事情可能会变得非常错误,老实说,您的优势列表听起来吸引力不足,无法冒险。其中大多数可以通过单个数据库来完成。

评论


我们实现了为多个客户提供服务的多重列表数据库。在客户开始想要自定义结果的情况下,我们陷入困境。为了解决此问题,我们克隆了存储的proc,并为其赋予了唯一的客户名称前缀,然后从应用程序内部对其进行了调用。另一方面,我们售出了150个网店,每个网店都有各自独立的数据库(97%相同)。所以两者都可以做到,取决于情况。

– Michael Riley-又名Gunny
2011年5月12日19:38

真好我并不是说这不可能完成,只是说它听起来并不容易,对您来说对Gunny有益。

–eiefai
2011年5月12日20:17

如果您可以举出错误原因的示例,那就太好了。当然,要使所有数据库保持最新是很困难的,但是要决定我们必须能够衡量优缺点。

–鲍里斯·卡伦斯(Boris Callens)
16年8月8日在11:34

#3 楼

您可能希望保留另一个数据库来跟踪每个客户所处的版本,以便可以跟踪哪些客户已经或未进行最后一轮修改。

编写升级脚本不会并不是那么困难...您可以编写一些内容来查看数据库的目录,并进行必要的更改以使每个数据库都达到最新版本,可能会跳过由于某些原因不应该升级的数据库。

正如Gaius指出的那样,由于mysql的“数据库”只是模式,如果它们都在同一服务器实例上运行,则可以限定要修改的表的名称,或从中获取信息:

alter schema.table ...
select ... from schema.table


...

如果您开始在多台服务器之间分解,您仍然可以编写一些脚本来建立与多台服务器的连接,您可以应用所有更改;对于分析,同样,您可以使用主数据库中的联合表设置一堆数据库链接,以便从一个位置访问数据,就像您只是从表中读取数据一样。

。 。

此外,请注意,他们没有使用mySQL进行堆栈交换,而是在使用SQL Server。

我也不知道那里有什么样的性能开销那样规模的mysql,我想我从来没有超过mysql的30个“数据库”。

评论


为什么不在数据库本身中保留版本信息表?

–鲍里斯·卡伦斯(Boris Callens)
16年8月8日在11:34

@Boris:因为当您有数十个或数百个数据库时,要连接到每个数据库以要求提供其版本会比较麻烦。每个人都可以跟踪自己的想法不是一个坏主意,但是拥有一个DBA主列表也是值得的

–乔
16年8月8日在14:26

#4 楼

我有一个Web / DB Hosting客户端,该客户端具有750多个客户数据库,这些数据库具有相同数量的表(162)和相同的表结构。合并后,我的客户的所有客户数据总计524GB(95%的InnoDB)

想象一下,所有这些数据库都通过循环复制在九台DB服务器上争夺13G的innodb缓冲池。仅凭该硬件配置进行扩展还不够。立即,我们建议该客户端进行扩展。

我们最近将此客户端迁移到了3台功能强大得多的DB服务器(不惜一切代价,请远离高写入环境中的SSD,始终!!!) !)。我们将它们从MySQL 5.0.90升级到了MySQL 5.5.9。几乎立即就能看到巨大的差异。

还必须考虑横向扩展,因为如果您有数百个客户端使用相同的内存和磁盘资源,横向扩展会线性减少其使用量(O(n)),其中n是基于多主控环境中数据库服务器的数量。

对于我的客户,我公司正在将其从9个数据库服务器(Quad Code,32GB RAM,824G RAID10)减少到更快的数据库MySQL 5.5.9的服务器(双HexaCore [对应12个CPU],192GB RAM,1.7TB RAID10)(要利用多个CPU)。此外,想象一下150个innodb缓冲池在50个分区中,每个分区3GB(多个InnoDB缓冲池是MySQL 5.5中的一项新功能)。较小规模的扩展但大规模的扩展已经为我的客户的独特基础结构提供了帮助。

故事的主旨:如果表的设计不正确,向上或向外扩展并不总是解决方案。我的意思是:如果索引页面的多列索引的键填充不平衡,则从索引的不平衡部分查询键会导致在表扫描后进行表扫描,或者至少由于MySQL Query的排除而无法使用的索引优化器。根本没有适当设计的替代品。

评论


我知道这确实很老,但是我想知道您对高写入环境中的SSD的评论背后的原因是什么。你能启发我吗?

– Elixenide
2015年10月29日在15:34

@EdCottrell我的猜测是这是有关SSD有限写入的警告。在某种程度上,这使驱动器无法使用,我相信在过去的几年中,TRIM和其他技术已经融入SSD控制器芯片中,从而在很大程度上缓解了这些问题,因此SSD写入尽管我确信这仍然是一个问题,但它并没有太大的问题。

– shaunhusain
16年1月26日,0:30

#5 楼

MySQL在不同的目录中创建数据库,因此很大程度上取决于基础操作系统以及它可以处理的文件夹/文件处理数量。对于现代操作系统而言,这不应该是一个问题,但这是很多瓶颈的来源。

#6 楼

没有任何内容表明您必须托管不同版本的数据库或应用程序。仅通过为每个客户分配一个数据库并拥有一个版本的数据库和应用程序来简单地隔离数据有什么问题?当然,每个客户数据库都必须从当前工作版本的模板中克隆。从安全和数据隔离的角度来看,我认为这是理想的。

我唯一看到的缺点是,在创建新版本时必须手动更新每个数据库。不过,这很容易实现自动化。