在单个数据库、多租户 (SQL) 上设计 SaaS

yoh*_*sen 5 mysql sql database-design roles saas

我正在研究SaaS产品,并试图找出为我的场景设计数据库的最佳方式,我认为这是非常标准的。

我不应该说我没有设计这样一个数据库的经验。

我厌倦了在线研究,但实际上我找不到任何有关实施的信息。有很多比较不同的多租户架构。

对于多租户方法,我决定使用单个数据库- 似乎是最合适的。

以下是应支持的基本列表:

  • 多个客户端,全部分开,它们之间不共享数据。
  • 每个客户都有自己的用户群(员工/雇员)。
  • 客户的员工对系统有不同的访问级别(接触不同的区域,执行某些操作的能力)
  • 每个客户都有自己的客户。

我可以将头tenant_id放在任何桌子上都属于该租户的基本概念上。我想我的问题更多是关于如何将它与每个客户的工作人员的不同访问级别结合起来。

你会怎么做?任何参考这种数据库的一些实现?

谢谢


更新

在@dmfy 回答之后,我想了想,想出了这个解决方案:

account
 -id
 -name

user
 -id
 -account_id
 -username
 -password

role
 -id
 -account_id
 -name

user_role
 -user_id
 -role_id

access
 -id
 -role_id
 -name

role_access
 -role_id
 -access_id

session
 -account_id
 -user_id
 -token
Run Code Online (Sandbox Code Playgroud)

我来解释——

该role表本质上是与权限/访问级别列表相关联的用户“组”。

该access表代表单个权限。平台的一个区域,可以(或不能)执行的操作。

session成功登录后会在表中创建一行。每次调用服务器时,如果用户已通过令牌验证,我将查找该用户的角色(使用session.user_idonuser_roles并access使用role.idon收集其列表role_access.role_id)。

获得访问列表后,我可以检查请求并查看是否允许用户执行该操作。

  • 笔记
    • role可以为每个租户/帐户定制(例如,一个可以有“管理”和“员工”,另一个可以有“管理”、“支持”和“销售”),因此与account.
    • access另一方面,是平台范围的。该平台在所有租户中具有相同的区域和操作集。因此无需将其与特定帐户相关联。
    • 对access查找的改进可能是在登录时将访问列表存储在会话中,以消除双重连接(获取所有用户的角色,获取所有角色的访问列表)。

问题

  • 首先,您对设计的总体看法是什么。你看到任何缺陷吗?
  • 被保存account_id在session真正需要的/一个好主意?
  • 让服务器检查用户是否有权访问某个资源是执行此操作的标准方法吗?有没有办法将其作为自身查询的一部分(例如从数据库本身获取错误)?

dmf*_*fay 2

听起来您正在将数据库用户与应用程序用户混为一谈。在具有共享架构模型的 SaaS 产品中,个人用户无法直接访问数据库;相反,您的应用程序作为单个用户进行连接,对其所需的所有对象拥有适当的权限。您担心的是用户可以访问应用程序的哪些区域以及他们可以执行哪些操作。这意味着您需要将授权模型构建到架构中。

最简单的模型有两个访问级别:普通用户和管理员。这可以用一个users表来表示,该表具有tenant_id将各个登录与正确的客户端相关联的表和一个is_admin标志。然后,您的应用程序将确保只有设置了该标志的用户才能访问管理功能。如果您的授权模型更复杂,请适当地设计您的架构(例如,users可能与 具有多对多关系)。roles

另请注意,tenant_id仅与直接相关的表严格需要列tenants;如果你有一个profiles带有 a 的表user_id,则可以通过 追溯到租户的关系users。在某些情况下,添加tenant_id以避免长连接链可能是有意义的。