Django和Postgresql的分层多租户架构,使用独立的架构

时间:2018-11-08 11:29:28

标签: django postgresql database-design architecture multi-tenant

我有一个django应用,其中包含客户端和链接到这些客户端的多个用户,我想将系统迁移到分层的多租户体系结构。

层次部分

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

多租户部分

我想将所有客户端的数据存储在单独的架构中。但是有些数据与客户端无关,因此我想将这些数据存储在“公共”模式中。

研究Building Multi Tenant Applications with 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 个答案:

答案 0 :(得分:1)

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

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

如果您希望能够一次查看来自多个客户端的数据,那么采用隔离模式的多租户架构不是正确的选择。消除了替代方案之后,我认为仅剩下一种方法。您必须对来自同一表中不同客户端的行使用共享模式多租户。

具有共享模式意味着来自不同客户端的数据分离较少,但是它提供了一种简单的方法,可以在需要时一次显示来自多个客户端的数据。通常的实现方法是在查询的where子句中添加术语,以确保仅返回对登录用户应可见的数据。

您可能考虑的另一种可能性是在数据库中使用行级安全性。通过这种方法,每个客户端将拥有自己的Postgres用户帐户,并具有一项策略,该策略将访问权限限制为仅访问适用于他们的行。这从确保应用程序层到数据库层的正确安全性负有一定的责任,这是有利有弊的。这样做的好处是,与在应用程序的整个数据访问部分中相反,安全性仅需在数据库中实施一次。一个可能的缺点是数据库可能需要做更多的工作。

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