用于单独客户帐户的单个或单独数据库?

时间:2010-12-15 11:56:53

标签: database-design

我正在开发一款从智能卡收集数据的应用。我希望能够将该应用程序作为多个客户帐户的Web服务运行。问题是,我应该为每个帐户创建一个单独的数据库,还是应该设计一个包含所有帐户数据的数据库?首先,我认为单个数据库是明显的答案,但它导致AccountID必须在任何地方,表,索引,约束,查询,检查等中使用。

在这个应用程序中,没有一个字节的数据要在帐户之间共享。

首先,让我们看看一个帐户的单独数据库的外观:

CREATE TABLE CardHolder ( 
    CardHolderID int, -- primary key
    CardHolderUniqueName nvarchar(30) );

CREATE TABLE SmartCard (
    SmartCardID int, -- primary key
    CardHolderID int,
    CardUniqueName nvarchar(30) );

添加一些唯一性约束,

ALTER TABLE CardHolder ADD CONSTRAINT UQ_CardHolderName UNIQUE (CardHolderUniqueName);
ALTER TABLE SmartCard  ADD CONSTRAINT UQ_CardName UNIQUE (CardUniqueName);

现在,如果我将所有内容放在一个数据库中,这意味着多个帐户可以处理相同的CardHolders和智能卡,但帐户不应该看到彼此的数据。因此,SmartCard在帐户中是唯一的,但不在整个数据库中。因此,每个约束都必须包含AccountID,

CREATE TABLE CardHolder ( 
    CardHolderID int, -- primary key
    CardHolderUniqueName nvarchar(30),
    AccountID int );

CREATE TABLE SmartCard (
    SmartCardID int, -- primary key
    CardHolderID int,
    CardUniqueName nvarchar(30)
    AccountID int );

ALTER TABLE CardHolder 
    ADD CONSTRAINT UQ_CardHolderName UNIQUE (AccountID, CardHolderUniqueName);
ALTER TABLE SmartCard
   ADD CONSTRAINT UQ_CardName UNIQUE (AccountID, CardUniqueName);

在实际的数据库中,会有更多的表,列和多个索引(用于按expirydate等列出等),并且必须包含AccountID列。

对我来说似乎有些混乱,首先将所有帐户放在一个数据库中,然后通过在每个表中包含一个AccountID列以及几乎每个约束和索引来分隔它们。我还需要找到或发明某种行级安全性,以防止用户访问其他帐户的数据。那么,我是否有为每个帐户创建单独数据库的有效借口,或者“真正的数据库设计者”是否始终将所有内容保存在单个数据库中?

3 个答案:

答案 0 :(得分:6)

在设计多租户应用程序时,有几点需要考虑,包括,如您的问题所述,架构设计,但也应考虑许可证成本,可扩展性等内容。 This article describes the three most common approaches for designing a multi-tenant application,包括利弊。看看这个。

答案 1 :(得分:5)

我们在这里走了两条路线。我们有一个共享数据库,适用于不需要自定义的小型客户端,以及适用于企业客户的单独数据库(以及应用程序代码库)。

两者都有其优点和缺点。在共享数据库中,所有需要的是一个错误的查询,其中有人忘记使用clientid并且数据暴露给其他客户端。在五年内,我看到这种情况只发生一次,但这是一个让我们成为客户的重大噩梦。如果你走这条路,请确保你有一个好的QA团队,在将代码发布到prod之前检查确切的。如果数据库具有模式,则可以使用模式中的视图来阻止其他客户端数据的数据访问。如果客户只拥有他们观点的权利,那么他们就可以看到其他人的数据。这是设置的更多工作。

但是,单独的数据库可能成为维护更改的噩梦。但是,如果您销售升级产品,则可以采用这种方式,因为并非每个客户都会购买每次升级。只需确保您有一个良好的跟踪机制来了解每个客户端所使用的版本,并且您使用源代码控制来按版本跟踪所有数据库更改,因此您可以轻松升级。

如果您不打算进行自定义,您可能会发现无论如何都有单独的数据库导致该方向。当他们是共享数据库时,告诉他们更容易。

此外,我们发现有些自定义项对其他客户有用,但因为它们是在单独的应用程序和数据库中开发的,所以它们由不同的团队为不同的客户端重新开发,最终你有6种方法可以做同样的事。对于在客户端工作的人员(例如将客户端数据导入数据库的人员)而言,这将成为一个主要的痛苦。我个人更喜欢一种数据库方法。

关于需要整合或分离报告数据的问题的另一点。如果报告将始终仅由客户进行,那么您可以将它们分开,但如果您需要进行报告(例如您自己的内部财务报告),那么如果您拥有统一数据库,则会更容易。我提出这个问题是因为人们往往会忘记报告,直到设计完成之后,当你这样做时它会引起一些非常讨厌的问题。

答案 2 :(得分:2)

恕我直言,只有一种方法。多个数据库。

  1. 这不仅是完全安全的数据,而且绝不能共享
  2. 它还使模式能够彼此独立地更改。我的意思是,随着时间的推移,也许一个租户比其他所有的客户都大得多,因此必须满足特殊需求。
  3. 可以轻松地为独立数据库制定备份,还原操作和策略
  4. 约束和独特性更容易,更自然地表达