大型Web应用程序的数据库架构

时间:2009-05-10 15:11:53

标签: database-design web-applications saas

许多SaaS Web应用服务都有基于公司的概念。因此,使用该服务的每个公司都有自己的一组用户,文件和其他数据。 Web应用程序通常如何在数据库端处理此问题?他们是否为每家公司创建一个新数据库(包含与该公司相关的数据表)?或者他们是否有某种company_id关系来从单个数据库中选择相关数据?

4 个答案:

答案 0 :(得分:12)

几个月前,我们在一个组织经常使用的产品中确实遇到了这个问题,而这些产品又为多个客户提供服务。他们来找我们要求我们修改我们的SaaS系统,这样他们就可以为每个客户创建完整的,独立的网站(我们构建了一个在线的,特定于域的网站构建工具)。

一个简短的总结:将每个人放在一个数据库上似乎显而易见,但是,当你深入探究时,你会发现它并不总是干涸。在您继续操作时,您需要记住一些挑战。几点:

首先,仅将“Company_id”添加到几个表中是不够的。实际上,尽管Sai的评论认为每个公司都有一个数据库/应用程序是荒谬的,但由于托管多个独立客户端的SaaS系统的潜在复杂性,绝对存在这种情况。如果您只是服务一些不同的公司(例如为他们创建发票),那么Sai的评论是完全正确的。但是,如果要向多个组织提供软件应用程序,则复杂性要高得多,而且离散数据库可能正常。

其次,准备好在多客户端数据库中进行更复杂的用户查询和报告工作。例如,在构建我们的用户查询功能时,我们必须绝对确定组织之间不存在“渗透”,因为涉及HIPAA保护的数据。这意味着查询和报告功能所需的工程水平远远超过以前的水平。在我们的例子中,我们的查询功能非常灵活,基本上允许用户动态构建查询(受制于一些相当严格的约束,显然 - 我们不接受SQL!)。因此,无论数据的来源或提交查询的工作人员的权限如何,我们都必须确保每个查询都自动修改为使用“Company_ID”约束。皱纹?我们的“超级用户”分析帐户必须能够在没有这种限制的情况下运行查询...

第三,你可能还没有预料到需要分开多少东西。例如,我在网站中构建了一个非常复杂的“设置”对象,它在启动时从数据库中提取设置,并将它们保存在“应用程序”对象中(这是一个.NET应用程序)。这一切都需要浮动才能处理多个组织。

另一个例子,以前对我们来说唯一的字段(例如登录)现在必须作为Company_ID,LoginID键的一部分完成。如果你是从头开始构建,这不是一个很大的想法,但我们正在进行改造,所以它是。

无论如何,当我继续构建时,我很惊讶地发现需要做多少工作才能做到这一点。

第四,我总是使用“元编程”方法构建软件。也就是说,我很少构建一个单一目的页面,而是经常构建一个高度可定制的框架,以便于最终用户定制和内部代码重用。虽然我预计这将有助于向多组织数据库的过渡,但它往往没有!因为这样的编码通常起初相当复杂,所以浮动本组织通常比仅仅拥有一个香草网页更困难。

最后,如果不需要共享数据(例如分析整体使用模式),那么您可能希望坚持使用离散数据库来简化扩展。当您添加新的多组织数据库(第二个离散系统)时,我们的扩展通常涉及突然出现增长激增的现有客户端。将它们从现有数据库剥离到新服务器上比仅使用现有数据库迁移到新服务器要困难得多。

考虑到所有这些警告,您可能会认为我建议您不要构建能够在单个数据库上处理多个组织的系统。但事实并非如此:采用多组织方式有一些真正的胜利!使用分析,跨组织报告,应用程序部署等都得到了显着增强。我只想向您提供我们的经验,希望它能帮助您预测您可能遇到的一些困难。

答案 1 :(得分:2)

绝对是company_id。

为每一件事创建一个新表 - 更不用说一个新的DATABASE - 会很荒谬(而且确实是许多每日WTF帖子的素材)。

这就是使用关系数据库的全部意义 - 将事物链接在一起。

如果你需要让数据库更大,有很多方法可以做到(主/从,主/多层,双主,水平扩展,只需购买大量的RAM等)。

FWIW:我的上一个应用程序有大约1200万用户(每天约30万);它有两个数据库(水平扩展;由以前的人完成。我不同意这个决定,并且只会使用奴隶)。

编辑:警告 - 假设您只是通过您的应用程序(其Web界面或API)公开访问权限。

如果你真的需要直接向客户公开数据库,a)告诉他们再思考,因为这是一个坏主意,并且b)那么你可能需要在更容易维护的东西之间做出艰难的选择,以保留所需的防火墙。但是srsly,如果你能提供帮助,你不想去那里。

答案 2 :(得分:1)

我最近发现SaaS中存在这样的名称,当公司之间共享应用程序和数据库时:

Multitenancy

答案 3 :(得分:1)

将软件作为服务运行时,在选择数据库策略时总会考虑一些事项。每个客户端单独数据库的两个参数是备份和(安全感)。如果你有一个带有谨慎的customer_id字段的数据库,并且客户666搞砸了,并且想要恢复他昨天的数据,你就可以从事一些工作了。

该客户有时也需要每个客户一个数据库,因为数据可能是敏感的。他可以理所当然地认为,将数据放在不同的数据库中并设置良好的安全性会更加节省。

-Edoode