用于单独客户帐户的单个或单独数据库?
我正在开发一个从智能卡收集数据的应用程序。我希望能够将应用程序作为多个客户帐户的 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);
现在,如果我将所有内容放入一个数据库中,则意味着多个帐户可以处理相同的持卡人和智能卡,但帐户应该看不到对方的数据。因此,智能卡在一个帐户内是唯一的,但在整个数据库中不是唯一的。因此,每个约束都必须包含一个 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);
在实际的数据库中,将会有更多的表、列和多个索引(用于按到期日期等列出),并且 AccountID 列必须包含在任何地方。
对我来说,这似乎有点混乱,首先将所有帐户放入一个数据库中,然后通过在每个表以及几乎每个约束和索引中都有一个 AccountID 列来分隔它们。我还需要找到或发明某种行级安全性,以防止用户访问其他帐户的数据。那么,我是否有一个有效的借口为每个帐户创建一个单独的数据库,或者“真正的数据库设计者”总是将所有内容保存在一个数据库中?
I'm working on an app that collects data from smartcards. I want to be able to run the app as a web service for multiple customer accounts. The question is, should I create a separate database for each account or should I design a single database that holds all accounts' data? First, I thought that a single database was the obvious answer, but it results in the AccountID
having to be used just about everywhere, in tables, indexes, constraints, queries, checks etc.
In this app, there is not a single byte of data that is to be shared between accounts.
First, let's look at how a separate database for one account would look:
CREATE TABLE CardHolder (
CardHolderID int, -- primary key
CardHolderUniqueName nvarchar(30) );
CREATE TABLE SmartCard (
SmartCardID int, -- primary key
CardHolderID int,
CardUniqueName nvarchar(30) );
Add to that a few uniqueness constraints,
ALTER TABLE CardHolder ADD CONSTRAINT UQ_CardHolderName UNIQUE (CardHolderUniqueName);
ALTER TABLE SmartCard ADD CONSTRAINT UQ_CardName UNIQUE (CardUniqueName);
Now, if I put everything in one database, it means that several accounts could handle the same CardHolders and SmartCards, but the accounts should not see each others data. Because of this, a SmartCard is unique within an account, but not within the entire database. So, every constraint must include an 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);
In the actual DB, there will be loads of more tables, columns and several indexes (for listing by expirydate etc etc) and the AccountID column has to be included everywhere.
It seems a bit cluttered to me, first putting all accounts in a single database, and then separating them by having an AccountID column in every table and just about every constraint and index. I'd also need to find or invent some sort of row level security to keep users from accessing other accounts' data. So, do I have a valid excuse for creating a separate database for each account, or do "real db designers" always keep everything in a single database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
设计多租户应用程序时需要考虑几件事,包括您的问题所述的架构设计,但还应考虑许可证成本、可扩展性等因素。 本文介绍了设计多租户应用程序的三种最常见方法,包括优点和缺点。一探究竟。
链接到该文章的 pdf 版本: http ://ramblingsofraju.com/wp-content/uploads/2016/08/Multi-Tenant-Data-Architecture.pdf
There are several things to have in mind when designing a multi-tenant application, including, as your question states, the schema design, but things such as license costs, scalability etc. should also be taken into account. This article describes the three most common approaches for designing a multi-tenant application, including pros and cons. Check it out.
Link to a pdf version of the article: http://ramblingsofraju.com/wp-content/uploads/2016/08/Multi-Tenant-Data-Architecture.pdf
恕我直言,只有一种方法。多个数据库。
IMHO there is only one way. Multiple databases.
我们在这里两条路都走了。我们为不需要定制的小型客户提供了一个共享数据库,为需要定制的企业客户提供了一个单独的数据库(以及与此相关的应用程序代码库)。
两者都有其优点和缺点。在共享数据库中,只需要一个错误的查询,即有人忘记使用 clientid,数据就会暴露给其他客户端。五年来,我只见过这种情况发生过一次,但这是一场重大噩梦,导致我们失去了一个客户。如果您走这条路,请确保您有一个优秀的 QA 团队,在将代码发布到产品之前准确检查这一点。如果您的数据库有架构,您可以在架构中使用视图来防止其他客户端数据的数据访问。如果客户只拥有自己观点的权利,那么他们就永远看不到其他人的数据。不过,这需要更多的工作来设置。
但单独的数据库可能会成为进行维护更改的噩梦。但是,如果您出售升级,则应采用这种方法,因为并非每个客户都会购买每个升级。只需确保您有一个良好的跟踪机制来了解每个客户端所在的版本,并使用源代码控制按版本跟踪所有数据库更改,以便您可以轻松升级。
如果您不打算进行自定义,您可能会发现拥有单独的数据库无论如何都会导致这个方向。当他们位于共享数据库上时,告诉他们“不”要容易得多。
此外,我们发现有些定制对其他客户会有帮助,但因为它们是在单独的应用程序和数据库中开发的,所以它们会由不同的团队针对不同的客户重新开发,最终您有 6 种方法可以做到这一点事物。对于跨客户端工作的人员(例如将客户端数据导入数据库的人员)来说,这成为一个主要的痛苦。我个人更喜欢单一数据库方法。
关于合并或分离的需要的另一点涉及数据报告。如果报告始终仅由客户完成,那么您可以将它们分开,但如果您需要使用合并数据进行报告(例如您自己的内部财务报告),那么如果您有一个统一的数据库,那就容易得多。我提出这个问题是因为人们往往会忘记报告,直到设计确定之后,当你这样做时可能会导致一些非常讨厌的问题。
We have gone down both routes here. We have a shared database for smaller clients who do not need customization and a separate database (and application code base for that matter) for Enterprise clients who do.
Both have their pluses and minuses. In the shared database all it takes is one bad query where someone forgot to use the clientid and the data is exposed to other clients. In five years, I have seen this happen only once but it was a major nightmare that cost us a client. If you go this route, make sure you have a good QA team that checks for exactly that before releasing code to prod. If your database has schemas, you can use views in schemas to prevent data access of other client data. If the client only has the rights to their views, then they can;t ever see anyone else's data. This is more work to set up though.
But the separate databases can become a nightmare to make maintenance changes to. However, if you sell your upgrades, this is the way to go as not every client will buy each upgrade. Just make sure you have a good tracking mechanism to know what version each client is on and that you use source control to track all database changes by version, so you can easily upgrade.
If you don't intend to have customizations, you may find that having separate datbases leads in that direction anyway. It's a lot easier to tell them no when they areon a shared database.
Further we've found that there are customizations that would be helpful to other clients but because they are developed in a separate application and database, they get redeveloped by a different team for a different client and you end up with 6 ways to do the same thing. This then becomes a major pain for people who work across clients such as the people who import client data to the databases. Personally I prefer the one database approach.
Another point concerning the need to consolidate or separate out concerns reporting on the data. If reporting will always be done only by client, then you can separate them out, but if you need to do reporting (such as your own internal finacial reporting) woth consolidated data, it is much easier if you have a consolidated database. I bring this up becasue people tend to forget about reporting until after the design is set and it can cause some pretty nasty problems when you do that.