使用多个数据库实例构建Web应用程序还是仅使用单个实例?

24

我目前正在设计一个网络应用程序,客户将以公司的形式注册。每个公司将有自己的一组用户。在设计过程中,我想知道哪种方法最有效。我看到像FogBugz或Basecamp这样使用子域的网站。在使用子域的情况下,是否对每个子域都需要一个数据库实例?我想知道是否建议为每个公司设置一个数据库实例,还是应该拥有某种公司表,并从一个数据库中管理公司和用户数据/凭据。

哪种方法是最好的?是否有关于此主题的文献(例如任何网站或书籍)?

谢谢!


5
每个选择都有其优点。单独的数据库意味着需要更多的维护时间用于修补/修复/更新,以及更多的行政开销。但这也意味着数据更容易被隔离,可以将用户分配到不同的数据库服务器上进行扩展。实际上,这取决于你的最终目标和需求是什么。对于你的问题并没有银弹解决方案。每个决策都有两面性,其中一些确实是50/50的,你只能做出选择并继续前行。评估你的需求,并选择最适合这些需求的解决方案。 - xQbert
1
我赞同xQbert的观点。例如,对于我们正在构建的应用程序来说,业务用户不看到其他人的数据非常关键。当将它们保存在单个数据库中时,您始终存在更高的风险,即测试中未检测到的错误会导致租户之间的泄漏。 - user3141326
1个回答

30
你需要权衡一下选择,因为其中一些内容可能是基于个人观点的,并且在你的实现中可能不可行。话虽如此,出于以下原因,我建议采用单数据库方法:
1. 维护: 每注册一个客户端就运行一个数据库,这将很容易导致任何对应用程序模式所做的更改或升级都必须应用到每个数据库实例上。这会很快变得荒谬。
2. 便利性: 你可能需要分析和使用统计数据,或者想要管理所有这些数据库的一些方式。与尝试聚合所有数据库相比,查询单个数据库相对简单。这不会扩展。
3. 可扩展性*: 如第二点所述,你需要一种特殊的聚合方式来查询有关客户端和整个应用程序的信息。你的应用程序越大,查询就越复杂。另一个问题是,如果一个客户端比另一个客户端更频繁地使用应用程序,你将被鼓励优化什么?你的应用程序,更大的客户端数据库还是较小的客户端数据库?别忘了任何你改变的事情都必须复制到所有数据库中。
4. 备份: 你可以轻松备份一个数据库,只需创建一个转储并将其存储在某个地方。有一千个客户端,现在你必须运行1000个数据库转储,并且要给它们命名得足够好,以便在单个数据库损坏时能够识别它们。如果这种情况发生了,你怎么知道?数据库错误将局限于特定的数据库,而不是整个应用程序。
5. 用户界面(UI): 一个用户注册或被邀请使用你的应用程序,并属于一个特定的客户端。你会将该用户帐户保存到客户端的数据库中吗?如果是的话,在用户想要更改密码或你想要给他们发送电子邮件时,如何处理该数据?所以,你告诉用户让你知道他们在哪个数据库中,以便你可以找到他们吗?
6. 简化: 每个客户端都有一个数据库,但是你想只使用一个数据库。如果不显着破坏事物,如何将它们合并在一起?如果使用自动递增的ID,则会出现主键冲突;如果您决定重新生成密钥,则书签URL将无法使用;跨表的外键将不再指向正确的记录。你的数据完整性会降低。
你提到了通过自定义子域名提供其产品的“白标签”服务。我不知道这些服务是如何运作的,但是子域名只是他们DNS区文件中的一个基本CNAME或A记录。添加这些的过程可以自动化,并且应用程序的设计和一些服务器配置可以处理将这些子域名链接到正确的帐户和数据上。它们只是URL,因此可能在后端,应用程序不区分:
http://client.example.com
http://example.com/client

总的来说,您可能会认为这些问题都是您可以并且更喜欢处理的事情。然而,请注意,这样做可能会自讨苦吃,通过设计一个良好的单一数据库架构和一个良好抽象的前端,您可以获得更多的收益。

*@xQbert提到使用多个数据库的实际好处,我修改了这个答案以澄清我的关注点在于其他方面。


1
感谢fuzzyDunlop提供了非常详尽的答案。我一直倾向于这样做,但开始怀疑自己。看来我走在了正确的方向上。 - ralph

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