当前位置: 首页 > 知识库问答 >
问题:

使用Django和Postgresql的分层多租户体系结构使用单独的模式

牟稳
2023-03-14

我有一个django应用程序有客户端和多个用户链接到这些客户端,我想将系统迁移到分层多租户架构

分层部分

客户端可以递归地包含其他客户端。例如,客户端A包括客户端B和客户端C。如果用户客户端A登录系统,用户将看到客户端B和客户端C的数据。如果客户端B的用户登录系统,用户将只看到客户端B的数据。

多租户部分

我想将所有客户机的数据存储在单独的模式中。但有些数据与客户机无关,所以我想将这些数据存储在“公共”模式中。

当我研究使用Django构建多租户应用程序时,我看到了这一部分:

def set_tenant_schema_for_request(request):
    schema = tenant_schema_from_request(request)
    with connection.cursor() as cursor:
        cursor.execute(f"SET search_path to {schema}")

然而,要应用我上面提到的分层示例,我必须同时到达多个模式。我能做到吗?或者有其他方法来实现我的架构吗?

共有1个答案

公良浩邈
2023-03-14

您可以在PostgreSQL搜索路径中列出多个模式。如果同一个表出现在多个模式中,则只返回搜索路径中第一个模式的行。不同模式下的表中的行没有自动组合。所以这可能不是你想要的。

您可以重新构建应用程序,以便每个查询都从不同模式的表中选择数据,然后使用联合子句将这些结果连接在一起。虽然这将提供正确的结果,但应该清楚的是,以这种方式构建所有查询将使应用程序非常复杂,也不是一个好的计划。

如果您希望能够同时查看来自多个客户机的数据,那么使用隔离模式的多租户体系结构不是正确的选择。在消除了替代方案之后,我认为只有一种方法仍然存在。必须对同一个表中不同客户端的行使用共享模式多租户。

拥有一个共享模式意味着不同客户机之间的数据分离更少,但它提供了一种简单的方法,可以在需要的情况下同时显示来自多个客户机的数据。通常的实现方法是在查询的where子句中html" target="_blank">添加术语,以确保只返回登录用户应该可见的数据。

您可以考虑的另一种可能性是在数据库中使用行级安全性。使用这种方法,每个客户端都将拥有自己的Postgres用户帐户,其策略仅限制对适用于它们的行的访问。这将确保正确安全性的一些责任从应用程序层推给数据库层,这有优点也有缺点。一个好处是安全性只需要在数据库中实现一次,而不是在应用程序的整个数据访问部分。一个可能的缺点是数据库可能需要做更多的工作。

https://www.postgresql.org/docs/11/ddl-rowsecurity.html

 类似资料:
  • 我遇到了企业应用程序架构中的一个严重问题。我当前的应用程序是一个使用和的web应用程序。现在我需要在当前应用程序中支持多租户。 我的要求是,当用户登录到系统时,应该从相应的数据库中为用户提供数据。简而言之,我需要多个数据库支持,这可能会导致不同的连接字符串。那么我如何动态连接到数据库呢? 我的另一个问题是,租户(应用程序的特定客户端)可以动态注册自己,成功注册后,我需要创建一个包含数据库创建和初始

  • 我正在学习多租户应用程序,以及如何使用PostgreSQL的模式来实现这一点。 在研究这个主题时,我发现了一篇文章,作者描述了在多租户应用程序中使用PostgreSQL模式时的糟糕体验。主要问题是迁移性能差和数据库资源使用率高。 似乎只有一个模式(在租户之间共享表)会比每个租户有一个单独的模式带来更好的性能。但我觉得很奇怪。我的想法正好相反,因为较小表上的索引往往比较大表上的索引轻。 为什么在许多

  • 问题内容: 我正在开发将来的多租户Web应用程序,它将需要支持数千个用户。该应用程序是在基于Java的Play之上构建的!使用JPA / Hibernate和postgreSQL的MVC框架。 我看了盖伊·纳尔(Guy Naor)关于在Rails中编写多租户应用程序的演讲,其中他谈到了几种多租户方法(数据隔离度随着列表的增加而降低): 每个客户都有一个单独的数据库 一个为每个客户提供单独的架构和表

  • 我正在使用spring 3.0开发一个多租户应用程序,需要根据租户将文件上传到FTP服务器或从FTP服务器下载文件。对于每个租户,我们在同一个FTP服务器中有不同的FTP位置。您能帮助我根据租户使用spring 3配置/更改FTP位置吗。?

  • 我负责为我的公司建立一个复杂的系统,经过一些研究,决定卡门达符合我的大部分要求。但是我的一些需求并不常见,在阅读了用户指南后,我意识到有很多方法可以做同样的事情,所以我希望这个问题可以澄清我的想法,也可以作为其他人寻找构建类似东西的基础问题。 首先,我计划在Camunda BPM之上构建一个特定的应用程序。它将使用工作流和BPM,但不一定使用BPM/Camunda提供的所有东西。这意味着我不打算使

  • 我们首先需要在 UserDefinition 加载并缓存租户用户。 打开 Multitenancy.Web/ Modules/ Administration/ User/ Authentication 下的 UserDefinition.cs,并添加 TenantId 属性。 namespace MultiTenancy.Administration { using Serenity;