以数据为中心的应用程序:为不同的组织分开数据库表是个好主意?

时间:2013-06-03 14:37:12

标签: database-design relational-database database-schema

我正在构建一个可以注册多个组织的应用程序 自己并操纵一组企业表,如列表 客户,卖家,物品,销售订单等...我想知道是否 而不是只有一组表,它会更安全 为每个客户端分别设置一组表,所有表都在其中运行 同一个数据库。例如,数据库可以有 以下架构:

JOHNDOEFIRM_CUSTOMERS
JOHNDOEFIRM_CLIENTS
JOHNDOEFIRM_ORDERS
...

JAKEDOESONFIRM_CUSTOMERS
JAKEDOESONFIRM_CLIENTS
JAKEDOESONFIRM_ORDERS
...

依此类推,每家公司都有一套表格。表格是 每次公司注册时都会创建适当的前缀。 这可能具有以下优点:

  1. 如果一家公司不能意外地弄乱另一家公司的桌子会更安全
  2. 将对表进行特定于公司的自定义
  3. 与保持单独的数据库相比,这样做有什么好处 每家公司都一样吗?由于每家公司将有大约20-40个桌子, 表的数量是否会随着数量的增加而爆炸 用户,因此完全放慢了数据库的速度?

    有关刚刚描述的应用程序设计和问题的任何反馈 我在这篇文章中指出非常受欢迎,以及建议 注意事项。

    感谢。

2 个答案:

答案 0 :(得分:2)

  

我想知道是否只有一组表,为每个客户端分别设置一组表会更安全,所有表都在同一个数据库中运行。

如果要执行此操作,则每个客户端都有一组单独的表,这些表在不同的逻辑数据库中运行。 DBA更容易管理。

您基本上承认,在共享相同的数据库表时,您无法依赖应用程序代码来保持公司的分离。

  

由于每家公司将拥有大约20-40个表格,表格的数量是否会随着用户数量的增加而大幅增加,从而减缓了数据库的速度?

你要么为每家公司准备20到40张桌子,要么为所有公司准备20到40张桌子。无论哪种方式,存储量都大致相同。

如果每个公司都拥有自己的逻辑数据库,那么DBA可以灵活地将公司迁移到新的物理数据库。假设您可以将5家公司的表放在服务器上。换句话说,每个物理数据库有5个逻辑数据库。然后您的DBA知道要管理多少台服务器。

如果某个公司成比例地导致更多的数据库问题,那么该公司的逻辑数据库可以移动到自己的物理数据库,直到问题得到解决。

答案 1 :(得分:1)

您描述的问题通常称为“多租户架构”。没有正确或错误的答案 - 但有一大堆权衡取舍。

您的设计 - 每个客户的表命名空间 - 具有您提到的好处。每个客户端都有自己的隔离表,因此任何一个客户端都很难影响其他客户的数据,您可以将不同的版本应用于不同的客户端。但是缺点是非常可怕 - 每次更改应用程序时,最终都会更改数百个客户端表。如果您有共同的数据 - 货币,世界各国,大小 - 您必须要么跨客户端复制(JOHNDOE_COUNTRIES),要么只有一个打破“所有John Doe的表称为JOHNDOE_”一致性。单个错误 - 尤其是查询中的性能问题 - 可以扩展到您拥有的客户端数量,并且必须针对每个客户端进行修复。在您的应用程序代码中,您必须花时间更改每个数据库表的名称,这使得许多ORM解决方案更难以使用。

这里提到的替代选项 - 每个客户端的数据库 - 更加优雅。您保持客户端之间的分离,您可以将不同的客户端放在不同的物理硬件上以管理性能/可伸缩性,您不必破坏应用程序代码中的表名,并且您的构建/部署脚本要简单得多。但是,您仍然拥有整个“为每个客户端进行一次相同的代码更改”问题。它非常非常快速地成为一个问题 - 如果您的构建/部署脚本需要10分钟,那么当您拥有200个客户端时,将需要一整天来升级您的应用程序。

当然,您可以将client_id烘焙到数据库模式中 - 将CLIENT_ID作为CLIENTS,ORDERS等中的列。这意味着代码中的错误意味着一个客户端可能会影响另一个客户端的数据 - 但这种可能性仍然存在在其他情况下。例如,在选项1中破坏表名的代码可能包含一个选择错误客户端前缀的错误。

然而,一个拥有许多client_id的大型数据库来识别哪个客户“拥有”数据很多更容易管理 - 单个构建/部署脚本,修复和测试错误只发生一次,新功能只推出了一次。节省成本可能是巨大的。

所以,我的建议是开始使用一个带有CLIENT_ID的单个数据库,但是为每个客户端选择一个不同的数据库,以便将来可以扩展到多个数据库。我不会为每个客户使用不同的表。