如何设计SaaS数据库

22

我有一个为卡车公司开发的Web应用程序,我希望将其作为SaaS提供。如何设计数据库最好?

我应该为每家公司创建一个新的数据库吗?还是应该使用一个具有公司名称前缀的表的单个数据库?或者我应该使用一个具有每个表的唯一公司ID字段的数据库?还是有其他方法可以实现?


1
你所说的太模糊了。在你的应用程序中,“公司”代表什么? - Randy Minder
@Randy - 一个公司是一组具有访问相同数据权限的用户。因此,卡车公司A可能有5个用户访问其数据,而卡车公司B可能有20个用户访问完全不同的数据集。这有帮助吗? - Josh Curren
更常见的缩写是“SaaS”,通常,SAS指的是SAS公司。http://www.sas.com/。不清楚你是在谈论公司还是服务提供的想法。您可能需要修正您的问题。 - S.Lott
1
数据库设计和模式设计问题不适合在Stack Overflow上讨论。也许http://dba.stackexchange.com/是一个更好的选择。 - jww
2
我很欣慰人们认为这个问题有一个单一的正确答案,而且将其中一种方法指定为正确的可能会造成潜在的伤害。@jww是对的,这应该被投票为不相关主题——因为考虑因素太多了,所以不可能只有一个答案。 - David Aldridge
4个回答

31
大约十年前,我们面临着相似的情况,选择了为每个客户建立一个数据库。我们有数百个客户(不是数千个)。回顾过去,这是我们做出的最好决定之一。备份很容易。将单个客户复制到我们的办公室进行分析也很容易(只需使用最后一次备份即可)。扩展也很容易(将单个大客户移动到不同的服务器上可以释放紧张SQL服务器上的资源)。Joel和Jeff在Stack Overflow podcast中讨论过这个问题(不是最近的),而Joel也像我一样做了同样的事情......每个客户都有自己的数据库。虽然纯粹的数据库专家通常会主张把所有人都合并到一个数据库中,但我永远不会这样做。
-Don

2
我应该补充说明数据库本身是以客户的名称命名的。所有数据库中的表格都被命名为完全相同的名称。 - Don Dickinson
3
如何保持这个?如果模式发生变化,是否需要更改所有数据库的模式? - Allen Gingrich
哦,以下哪些流行的SaaS产品使用每个客户端一个数据库?Trello、Basecamp、Google Apps、Salesforce CRM、Freeagent、Xero、Workday... - David Aldridge
1
如果您拥有庞大的客户群,每个客户端一个数据库将会成为操作/维护的噩梦 - 因此,如果您没有专门的数据库团队,请不要这样做。 - Dharmendar Kumar 'DK'
这太疯狂了...你有数千个数据库吗?哇...所以当用户注册时,你会为他们创建一个新的数据库?我很想了解更多关于这个设计的细节。 - uberrebu

11

我应该为每个公司创建一个新的数据库吗?

是的 - Don Dickinson是正确的。但请见下面的细化。

还是我应该使用一个数据库,其中表具有公司名称的前缀?

当然不!更改不同客户端的数据库查询将让您发疯!此外,您几乎肯定会运行动态SQL(在运行查询之前在代码中更改表名),这会损害性能,因为大多数服务器喜欢缓存查询计划和中间结果 - 如果表名不断更改,则无法实现缓存。

还是我应该使用一个数据库,每个表只有一个,并向表添加公司id字段?

如果您想要为客户提供可扩展的模型,可能需要这样做。虽然为每个客户提供新数据库可以为您提供很多灵活性,但这也涉及成本和复杂性。您必须为处理已过期的客户创建新的备份计划和生命周期模型等。

因此,您可能会说“免费试用”和“铜牌”客户都被集中到单个数据库中,使用公司ID来将它们分开; “银牌”用户获得自己的数据库(但仍然在模式中保留customer_id字段,因此您不必在两个客户级别之间更改查询),而“金牌”客户获得自己的数据库服务器。

几年前我在一家SaaS公司做过类似的事情 - 客户通常很高兴拥有基础设施(即性能和韧性)以及功能的升级路径。


3
最后选项无法处理“青铜”客户想要升级到“白银”或“黄金”的情况。 - Dharmendar Kumar 'DK'

3
我们这里有一些数据库是共享客户的,而有一些则是每个客户都有自己的服务器和数据库。那些客户在自己的服务器上的数据库最容易管理,也最不可能因为某个开发人员忘记添加客户ID并意外将客户A的数据发送给客户B(这是一个不随机选择的例子)而导致问题。
让每个客户都在自己的服务器或服务器实例上可以使我们保持相同的数据库结构和名称,并且更容易传播所有服务器上的更改,因为我们不必更改数据库名称。
如果您确实为每个客户使用单独的实例,请确保设计和实施良好的系统以将所有更改传播到所有客户端。如果这些数据库失去同步,它们会变得非常难以维护。您会发现,如果让它们失去同步,每个客户都会要求更改,而您将拥有27种执行同一操作的方法。当它们在同一个数据库中时,您必须进行概括,而当它们分开时,您必须使用自我约束来确保新功能对每个客户端都是相同的。

0

这要看情况,我在一家公司工作,该公司有许多像其他公司一样被视为“内部业务单元”的部门。 因此,某些报告必须包括所有公司,客户账户也必须在公司之间共享。我们在表格中有一个需要填写的CompanyId字段。 前缀解决方案肯定是要避免的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接