代码之家  ›  专栏  ›  技术社区  ›  Marco Staffoli

共享数据的多租户应用程序(Asp net mvc+实体框架+Sql Server)

  •  6
  • Marco Staffoli  · 技术社区  · 15 年前

    我正在开发一个非常复杂的多租户应用程序架构。

    .

    3种完全不同的应用程序

    许多客户不仅仅使用一种类型的应用程序,还有3种不同的应用程序。

    附录A,附录B,附录C

    .

    每个应用程序都是多租户的

    每个应用程序都有自己的客户。

    附录A -客户A1 -客户A2

    附录B -客户B1 -客户B2

    附录C -客户C1 -客户C2

    .

    共享信息

    许多信息在不同的应用程序之间共享

    “客户A1” 需要操作或仅查看 “客户C1”

    .

    问题

    假设我使用的是Asp net mvc、EF、Sql Server。 是否正确实施?

    一个地点多个地区? 创建多个站点? 多分贝?只有一个分贝?过滤?Sql筛选视图?...

    一些应用示例?

    编辑

    还有。。。业务逻辑放在哪里?

    5 回复  |  直到 15 年前
        1
  •  2
  •   Tim Post Samir J M Araujo    15 年前

    我建议您首先在.Net之上构建自己的多租户工程堆栈(框架),它将处理多租户的所有要求,包括:面向租户的数据隔离、支持水平缩放、基于租户上下文和用户角色筛选视图、面向租户的数据模型扩展、面向租户用户界面定制,基于角色、权限和数据范围强制访问限制-对于不同的租户等可能有所不同。

    业务逻辑可以建立在这个框架之上。这种方法将为您的产品提供坚固和强大的工程基础。

    另一种选择是购买现成的多租户工程堆栈,将其安装在Visual Studio上,并将其用作开发模板。

        2
  •  0
  •   TFD    15 年前

    理想情况下,在多租户服务器中,使用一个应用程序时,您希望每个租户的数据库物理上不同,而不仅仅是指定数据属于哪个租户的列

    但不管怎样你都要确保 全部 数据库函数使用正确的数据库连接或租户列键。这才是真正的问题

    确保这一点的方法是 一个 做出此决定的每个应用程序的函数,并确保所有数据库函数在未调用此函数时失败(直接或间接,如下所示)

    e、 g.使用global.asax AuthenticateRequest或BeginRequest函数中的MVC,您可以验证用户是谁,然后计算他们需要使用哪个数据库连接,或者他们必须在该请求的每个查询中使用哪个租户列键。然后将其存储在会话变量等中

    如果你有三个应用,我会做三个独立的网站。他们可以通过共享项目共享公共类。如果可以单独部署,生活通常会更轻松

        3
  •  0
  •   Ahmad    15 年前

    这是一个具体的答案,但只是一些方面,你可以考虑时,设计这个。

    关于共享信息,我认为这里最重要的部分是定义客户之间的关系以及每个客户对其他客户的角色和权利。最好的方法是从确定具体可以做什么开始。

    例子:

    Read Only|cust1|cust2|cust3
    ---------+-----+-----+-----
    customer1| 1   | 1   | 0
    customer2| 0   | 1   | 0
    customer3| 1   | 0   | 1
    
    Write    |cust1|cust2|cust3
    ---------+-----+-----+-----
    customer1| 1   | 1   | 0
    customer2| 0   | 1   | 0
    customer3| 0   | 0   | 1
    

    因此在上面,customer1可以读写(更新)customer2的数据。

    这就是说,主要问题是建立这些关系的模型,即共享信息。使用@TFD的建议,当客户与相关租户id一起登录时,可以将这些关系加载到会话中。

    (根据提供的信息,我的另一个倾向是,这可能是每个应用程序的问题,而不是客户唯一的问题。为了说明这一点,将上表中的“cust”值替换为 App .)

    为每个应用程序创建单独的站点,因为我假设每个应用程序都有一个独特的用途,尽管有共享的功能。

    如果存在其他跨数据关系,则可能需要不同的配置数据库。数据库将存储每个应用程序的所有租户信息(包括与其他应用程序的关系)。这个建议的原因是,据我所见,您有三个独立的多租户应用程序,使用共享数据库方法彼此独立-但每个应用程序都需要在某种程度上与另一个应用程序交互。
    对于DB中的客户,我建议将“customers”表限制在Config DB中。然后,您可以根据每个应用程序的需求创建一个content DB。

        4
  •  0
  •   TheITGuy    15 年前

    我的建议是使用带有Slivelight和MVVM设计模式的PRISM。PRISM是为这样一种复合应用而设计的,其中每个应用程序都是独立的,也可以通过PRISM公开的事件相互通信。

        5
  •  -1
  •   Roopesh Shenoy    15 年前

    你可以有多种方法-因为应用程序是数据驱动的,所以构建一个数据库设计来保护数据是有意义的,即使在出现应用程序错误的情况下。

    一种方法是确保有用于访问任何表的存储过程,并将安全逻辑内置到存储过程中。您可以确保为每个客户使用不同的db用户名,并且该db用户名与映射表中的租户id进行映射。然后,存储的proc总是可以检查被请求/修改的数据是否实际属于映射到运行proc的db用户的租户id(通过使用上下文信息)。

    然后,您将需要某种方法来确保应用程序创建的数据库连接仅使用映射到该租户id的相应用户名。这意味着您需要一个以上的存储过程,该过程将提供此信息(可能以用户名/id作为输入),并且该存储过程应通过公共数据库用户名执行。记住,这是唯一一个需要为这个公共数据库用户提供执行特权的存储过程。

    这看起来像是编写了一堆额外的代码,但它确实有助于知道您的数据库将拒绝坏请求,即使是由于应用程序错误。你唯一真正非常小心的地方是你为这个用户id获得正确的租户db用户名和密码的地方,这应该是完全可能的。