我正在开发一款从智能卡收集数据的应用。我希望能够将该应用程序作为多个客户帐户的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列以及几乎每个约束和索引来分隔它们。我还需要找到或发明某种行级安全性,以防止用户访问其他帐户的数据。那么,我是否有为每个帐户创建单独数据库的有效借口,或者“真正的数据库设计者”是否始终将所有内容保存在单个数据库中?
答案 0 :(得分:6)
在设计多租户应用程序时,有几点需要考虑,包括,如您的问题所述,架构设计,但也应考虑许可证成本,可扩展性等内容。 This article describes the three most common approaches for designing a multi-tenant application,包括利弊。看看这个。
答案 1 :(得分:5)
我们在这里走了两条路线。我们有一个共享数据库,适用于不需要自定义的小型客户端,以及适用于企业客户的单独数据库(以及应用程序代码库)。
两者都有其优点和缺点。在共享数据库中,所有需要的是一个错误的查询,其中有人忘记使用clientid并且数据暴露给其他客户端。在五年内,我看到这种情况只发生一次,但这是一个让我们成为客户的重大噩梦。如果你走这条路,请确保你有一个好的QA团队,在将代码发布到prod之前检查确切的。如果数据库具有模式,则可以使用模式中的视图来阻止其他客户端数据的数据访问。如果客户只拥有他们观点的权利,那么他们就可以看到其他人的数据。这是设置的更多工作。
但是,单独的数据库可能成为维护更改的噩梦。但是,如果您销售升级产品,则可以采用这种方式,因为并非每个客户都会购买每次升级。只需确保您有一个良好的跟踪机制来了解每个客户端所使用的版本,并且您使用源代码控制来按版本跟踪所有数据库更改,因此您可以轻松升级。
如果您不打算进行自定义,您可能会发现无论如何都有单独的数据库导致该方向。当他们是共享数据库时,告诉他们更容易。
此外,我们发现有些自定义项对其他客户有用,但因为它们是在单独的应用程序和数据库中开发的,所以它们由不同的团队为不同的客户端重新开发,最终你有6种方法可以做同样的事。对于在客户端工作的人员(例如将客户端数据导入数据库的人员)而言,这将成为一个主要的痛苦。我个人更喜欢一种数据库方法。
关于需要整合或分离报告数据的问题的另一点。如果报告将始终仅由客户进行,那么您可以将它们分开,但如果您需要进行报告(例如您自己的内部财务报告),那么如果您拥有统一数据库,则会更容易。我提出这个问题是因为人们往往会忘记报告,直到设计完成之后,当你这样做时它会引起一些非常讨厌的问题。
答案 2 :(得分:2)