我有一个为货运公司构建的网络应用程序,我想以 SaaS 的形式提供。设计数据库的最佳方法是什么?
我应该为每家公司创建一个新数据库吗?或者我应该使用一个带有公司名称前缀的表的数据库?或者我应该对每个表使用一个数据库,然后在表中添加一个公司 ID 字段?还是有其他方法可以做到这一点?
我有一个为货运公司构建的网络应用程序,我想以 SaaS 的形式提供。设计数据库的最佳方法是什么?
我应该为每家公司创建一个新数据库吗?或者我应该使用一个带有公司名称前缀的表的数据库?或者我应该对每个表使用一个数据库,然后在表中添加一个公司 ID 字段?还是有其他方法可以做到这一点?
大约 10 年前面对类似的情况,我们选择了每个客户一个数据库。我们有数百(不是数千)客户。回首过去,这是我们做出的最佳决定之一。备份很容易。将单个客户端复制到我们的办公室进行分析很容易(只需进行最后一次备份)。扩展很容易(将单个大客户端移动到不同的服务器可以释放压力大的 sql 服务器上的资源)。joel & jeff 在堆栈溢出播客(不是最近的播客)上对此进行了讨论,并且 joel 做了同样的事情……每个客户都有自己的数据库。数据库纯粹主义者经常会争论将每个人都集中到一个数据库中,但我永远不会这样做。
-大学教师
我应该为每家公司创建一个新数据库吗?
是的——唐·狄金森在赚钱。但是,请参阅下面的改进。
或者我应该使用一个带有公司名称前缀的表的数据库?
主不!为客户更改不同的数据库查询会让你发疯!此外,您几乎可以肯定会运行动态 SQL(在运行查询之前在代码中更改表名),这会损害性能,因为大多数服务器都喜欢缓存查询计划和中间结果 - 如果表名这不起作用不断变化。
或者我应该对每个表使用一个数据库,然后在表中添加一个公司 ID 字段?
如果您想为您的客户提供某种可扩展的模型,您可能想要这样做。虽然为每个客户配置新数据库为您提供了很大的灵活性,但它也涉及成本和复杂性。你必须创建一个新的备份计划,有一个生命周期模型来处理过期的客户等。
因此,您可能会说“免费试用”和“青铜”客户都集中在一个数据库中,使用公司 ID 将它们分开;“白银”用户拥有自己的数据库(但您仍将 customer_id 字段保留在模式中,因此您不必更改两个级别的客户之间的查询),而“黄金”客户拥有自己的数据库服务器。
I did something similar a few years ago at a SaaS company - and customers are typically happy to have an upgrade path on infrastructure (read: performance and resilience) as well as features.
我们这里有一些共享客户端的数据库,还有一些每个客户端都有自己的服务器和自己的数据库。客户端在自己的服务器上的那些是最容易管理的,并且当一些开发人员忘记添加客户端 ID 并将客户端 a 的数据意外发送到客户端 b 时(不是随机选择的示例),最不可能导致问题。
将每个服务器或服务器实例保持在自己的服务器或服务器实例上允许我们保持数据库结构相同且名称相同,并且更容易将更改传播到所有服务器,因为我们不必更改数据库名称。
如果您确实为每个客户端使用单独的实例,请确保您设计并实现了一个良好的系统,用于将所有更改传播到所有客户端。如果这些数据库不同步,它们可能会变得难以维护。您会发现,如果您让它们不同步,每个客户都会要求更改,而您将有 27 种方法来做同样的事情。当它们在同一个数据库上时,您必须进行概括,当它们分开时,您必须使用自律来确保每个客户端的新功能都相同。
这取决于,在这里,我在一家有许多“内部业务部门”的公司工作,就像其他公司一样。因此,一些报告必须包括所有公司,客户帐户也必须在公司之间共享。在这里,我们在需要它的表中有一个 CompanyId 字段。前缀解决方案肯定是要避免的。