共享数据的多租户应用程序(Asp net mvc + Entity Framework + Sql Server)
我正在开发一个非常复杂的多租户应用程序架构。
。
3 种完全不同类型的应用程序
许多客户使用的应用程序不只有一种类型;有 3 种不同类型的应用程序。
应用程序 A、应用程序 B、应用程序
C。
每个应用程序都是多租户
每个应用程序都有其客户。
应用程序A - 客户A1 - 客户A2
APP B - 客户B1 - 客户B2
APP C - 客户C1 - 客户C2
。
共享信息
不同应用之间共享
许多信息在“客户 A1” 需要操作或仅查看“客户 C1” 拥有的数据的
。
问题
考虑到我正在使用 Asp net mvc、EF、Sql Server。 哪个是正确的实现?
一个站点和多个区域? 创建多个站点? 多个数据库?只有一个db?过滤? Sql过滤视图? ...
一些应用程序示例?
编辑
和...将业务逻辑放在哪里?
I'm developing a multi tenant app architecture that is quite complex.
.
3 completly different kind of app
Ther is no only one type of application used by many customers; ther are 3 different kind of applications.
APP A, APP B, APP C
.
Each APP is multitenant
Each app has its customers.
APP A
- customer A1
- customer A2
APP B
- customer B1
- customer B2
APP C
- customer C1
- customer C2
.
SHARED INFORMATIONS
Many informations are shared betwen the different apps
"customer A1" need to manipulate or only view data owned by "customer C1"
.
QUESTION
Consider that i'm using Asp net mvc, EF, Sql Server.
Wich is the correct implementation?
One site and many Areas?
Create multiple sites?
Multiple db? Only one db? Filtering? Sql filtered view? ...
Some application example?
EDIT
and... Where to put the business logic?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我建议您首先在 .Net 之上构建自己的多租户工程堆栈(框架),它将处理多租户的所有要求,包括租户明智的数据隔离、水平缩放支持、基于用户的租户上下文和角色、租户明智的数据模型扩展、租户明智的 UI 自定义、基于角色、权限和数据范围强制执行访问限制 - 这对于不同的租户等可能有所不同。
业务逻辑可以构建在这个框架。这种方法将为您的产品提供强大的工程基础。
另一种选择是购买现成的现成的多租户工程堆栈,将其安装在 Visual Studio 上并将其用作开发模板。
I would recommend that you first build your own multi-tenant engineering stack (Framework) on top of .Net which will handle all the requirements of multi-tenancy in terms of tenant wise data isolation, support for horizontal scaling, filtering of views based on the tenant context and role of the user, tenant wise data model extension, tenant wise UI customization, enforcing access restrictions based on roles, privileges and data scope - which could be different for different tenants etc.
The business logic can be built on top of this framework. This approach will provide your product a robust and strong engineering foundation.
The other alternative is to buy a ready to use multi-tenant engineering stack off the shelf, install it on Visual Studio and use it as a development template.
理想情况下,在具有单个应用程序的多租户服务器中,您希望每个租户拥有物理上不同的数据库,而不仅仅是指定数据所属租户的列
,但无论哪种方式,您都必须确保所有数据库功能使用正确的数据库连接或租户列键。这是真正的问题。
确保这一点的方法是每个应用程序仅具有一个函数来做出此决定,并确保所有数据库函数在未调用此函数(直接调用或调用)的情况下都会失败例如,
通过 global.asax AuthenticateRequest 或 BeginRequest 函数中的 MVC,您可以验证用户是谁,然后计算他们需要使用哪个数据库连接,或者他们在该请求的每个查询中必须使用哪个租户列键。然后将其存储在会话变量等中。
如果您有三个应用程序,我将创建三个单独的站点。他们可以通过共享项目共享公共类。如果它们可以单独部署,那么生活通常会更容易
Ideally in a multi-tenant server with a single app you want physically different databases for each tenant, rather than just a column specifying which tenant the data belongs too
But either way you have to ensure that ALL database functions use the correct database connection or tenant column key. That is the real issue
The way to make sure of this is to have only ONE function per app that makes this decision, and make sure all database functions fail if they have not called this function (directly, or indirectly as below)
e.g. With MVC in the global.asax AuthenticateRequest or BeginRequest function you can validate who the user is and then calculate which database connection they need to use or what tenant column key they must use in EVERY query for that request. This is then stored in a session variable etc
If you have three apps, I would make three separate sites. They can share common classes via a shared project. Life is generally easier if they can be deployed separately
这是一个具体的答案,但只是您在设计时可能考虑的一些方面。
关于共享信息,我认为这里最重要的部分是定义客户之间的关系以及每个客户相对于其他客户所拥有的角色和权利。最好的方法是首先确定到底可以做什么。
示例:
因此在上面,customer1 可以读取和写入(更新)customer2 的数据。
话虽这么说,主要问题是对这些关系(即共享信息)进行建模。使用@TFD 的建议,当客户与相关租户 ID 一起登录时,可以将这些关系加载到会话中。
(根据提供的信息,我的另一个倾向是,这可能是每个应用程序的问题,而不仅仅是客户的问题。为了说明这一点,请将上表中的“cust”值替换为
App
。 )为每个应用程序创建单独的站点,因为我假设每个应用程序都有独特的用途,尽管存在共享功能。
如果存在其他交叉数据关系,可能需要不同的配置数据库。数据库将存储每个应用程序的所有租户信息(包括与其他应用程序的关系)。提出此建议的原因是,据我所知,您使用共享数据库方法拥有三个彼此独立的独立多租户应用程序 - 但每个应用程序都需要在某种程度上与另一个应用程序交互。
就数据库内的客户而言,我建议将“客户”表限制在配置数据库中。然后,您可以拥有一个基于每个应用程序要求的内容数据库。
This is a concrete answer, but just some some aspects you may consider when designing this.
With regards to shared information, I think the most important part here is to define the relationship between customers and the roles and rights each customer has with respect to other customers. The best approach is to start with is identifying what exactly can be done.
Example:
So in the above, customer1 can read and write(update) customer2's data.
This being said, the main issue is model these relationships i.e. the shared information. Using @TFD's suggestion, these relationships can be loaded into session for when a customer logs on along with the relevant tenant id's.
(Based on the information provide, my other inclination is that this may be a per application concern and not a customer only concern. To illustrate this, replace the 'cust' values in the above tables with
App
.)Create separate sites for each application since I am assuming that each application has a unique purpose although there is shared functionality.
Maybe a different Config DB is needed if there are other cross data relationships. The DB would store all the tenant information (incl. relationships to other Apps) for each App. The reason for this suggestion is that from what I can see, you have three separate multi-tenant apps independent of each other using a shared DB approach - but each App need to interact with another App on some level.
In terms of customers within the DB, I would then suggest that the 'Customers' table be confined to the Config DB. You can then have a content DB based on each applications requirements.
我的建议是将 PRISM 与 Sliverlight 和 MVVM 设计模式结合使用。 PRISM 专为此类复合应用程序而设计,其中每个应用程序都是独立的,并且还可以通过 PRISM 公开的事件相互通信。
My suggestion is to use PRISM with Sliverlight and MVVM design patten. PRISM is designed for such kind of composite application where each application is independent and can also communicate with each other via Events exposed by PRISM.
您可以采用多种方法 - 由于应用程序是数据驱动的,因此构建即使在应用程序错误的情况下也能保护数据的数据库设计是有意义的。
实现此目的的一种方法是确保有用于访问任何表的存储过程,并且安全逻辑内置于存储过程中。您可以确保每个客户使用不同的数据库用户名,并且该数据库用户名映射到映射表中的租户 ID。然后,存储过程始终可以检查所请求/修改的数据实际上属于映射到正在运行该过程的数据库用户的租户 ID(通过使用上下文信息)。
然后,您将需要某种方法来确保应用程序创建的数据库连接仅使用映射到该租户 ID 的相应用户名。这意味着您需要另一个存储过程来为您提供此信息(可能以用户名/id 作为输入),并且该存储过程应该可以通过通用数据库用户名执行。请记住,这是唯一需要向该公共数据库用户授予执行权限的存储过程。
这可能看起来像编写一堆额外的代码,但知道您的数据库即使由于应用程序错误也会拒绝错误的请求,这确实很有帮助。您唯一需要真正非常小心的地方是为该用户 ID 获取正确的租户数据库用户名和密码的地方,这应该是完全可能的。
You can have multiple approaches - since the app is data driven, it makes sense to build a database design that secures the data even in case of application bugs.
One way to do this is ensure that there are stored procs for accessing any tables and the security logic is built into the stored procedures. You can ensure that a different db username is used for each customer, and that this db user name is mapped against that tenant id in a mapping table. Then the stored procs can always have a check that the data being requested/modified is actually belonging to the tenant id mapped to the db user who is running the proc (by using context information).
Then you will need some way to ensure that the db connection created by the application uses only the corresponding username that maps to that tenant id. This means you need one more stored proc that gives you this information (with probably username/id as the input) and this stored proc should be executable through a common db username. Remember, this is the only stored proc that needs to have execution priveleges given to this common db user.
This might look like writing a bunch of extra code, but it really helps to know that your db will reject bad requests even due to application bugs. The only place you have be really, really careful is the place where you get the right tenant db username and password for that user id, and that should be quite possible.