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

Bat*_*bix 13 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) );
Run Code Online (Sandbox Code Playgroud)

再加上一些唯一性约束,

ALTER TABLE CardHolder ADD CONSTRAINT UQ_CardHolderName UNIQUE (CardHolderUniqueName);
ALTER TABLE SmartCard  ADD CONSTRAINT UQ_CardName UNIQUE (CardUniqueName);
Run Code Online (Sandbox Code Playgroud)

现在,如果我将所有内容放在一个数据库中,这意味着多个帐户可以处理相同的CardHolders和SmartCards,但帐户不应该看到彼此的数据.因此,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);
Run Code Online (Sandbox Code Playgroud)

在实际的DB中,将会有更多的表,列和几个索引(用于按expirydate等列出等),并且AccountID列必须包含在任何地方.

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

Kla*_*sen 6

在设计多租户应用程序时,有几点需要考虑,包括,如您的问题所述,架构设计,但也应考虑许可证成本,可扩展性等内容.本文介绍了设计多租户应用程序的三种最常用方法,包括优缺点.看看这个.

  • 真的希望你在这里发布那篇文章的内容,因为链接腐烂现在这是一个死的答案. (4认同)

HLG*_*GEM 5

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

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

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

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

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

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