具有继承的数据库中的分层多租户组织

时间:2017-01-21 14:59:49

标签: sql sql-server inheritance multi-tenant

我正在计划一个基于数据库的系统,该系统将支持分层多租户以及功能和特权的继承。原理图结构如下:

             [0]
            /   \
           /     \
        [1]       [2]
       /         /   \
      /         /     \
  [11]      [21]       [22]
           /    \          \
          /      \          \
     [211]        [212]      [221]
                            /     \       
                           /       \      
                     [2211]         [2212] 

此处,表示层次结构中每个节点的数字仅为简单起见而设置,不应从中推断出任何数据。

第二个维度将由不同类型的用户给出,每个类型定义一组权限(例如,对系统正在处理的不同类型对象的访问类型)。

每个用户将分配给特定用户类型和特定租户(即上图中的节点)。分配给节点的用户将只具有可见性(如果分配了所需的权限) 相关用户类型)到同一租户内的对象和用户所属租户下的所有租户。

第三个维度将由以下事实给出:修改可以发生在分配给用户类型的默认权限上。例如,管理员用户类型可以创建新用户,但在子分支[221](和向下)除外。此例外将被定义为租户[221]的“掩码”。

因此,每当管理员登录其租户为[2212]的系统时,他收到的特权就是特权的超级位置:

 Privileges defined at [2212] overriding the
 privileges defined at [221]  overriding the
 privileges defined at [22]   overriding the
 privileges defined at [2]    overriding the
 privileges defined at [0]                   

例如,假设有5种不同的对象类型,即O1,O2,O3,O4和O5,权限为“N”(无),“R”(读取)和“W”(读取) /写)。默认情况下,管理员用户类型对所有对象类型都具有“W”特权。

现在,我们在节点[22]处的对象类型O3和O5上定义特权“R”,在级别[221]处定义对象类型O5的“N”特权。因此,分配给节点(租户)[2212]的管理员将继承以下权限:

Object Type    O1      O2      O3      O4      O5
=================================================
From [0]       W       W       W       W       W
From [2]       _       _       _       _       _
From [22]      _       _       R       _       R
From [221]     _       _       _       _       N
From [2212]    _       _       _       _       _
------------------------------------------------
Result ===>    W       W       R       W       N

现在,需要解决三个挑战:

  1. 当用户在节点(租户)X登录系统时,需要收集X的所有子节点以识别用户将(可能)具有可见性和操作权的对象,< / p>

  2. 当用户登录系统时,需要通过查看向上直到根节点来评估他的权限

  3. 数据库实现(SQL Server)的呈现方法是否合理?

  4. 在这三个问题中,“1”可以通过使用CTE来实现递归来简单地解决。然后我们留下问题2和3.我应该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

如果您将权限表规范化为(admin_id, org_id, obj, perm)而不是(admin_id, org_id, o1,o2,o3,o4,o5),则可以使用获取org id的所有祖先的查询以及使用您正在查找的管理员的权限表,并获取最接近正在登录的节点的权限。

rextester设置:http://rextester.com/MZRF65032

create table org(id int not null primary key, parentid int null);
insert into org values 
   (0,null)
  ,(1,0),(11,1)
  ,(2,0),(21,2),(211,21),(212,21)
  ,(22,2),(221,22),(2211,221),(2212,221);

create table objects (obj char(2));
insert into objects values ('O1'),('O2'),('O3'),('O4'),('O5');

create table admin (id int not null primary key, name varchar(32));
insert into admin values (1,'Zim');

create table permissions(
    admin_id int not null
  , org_id int not null
  , obj char(2)
  , perm char(1)
  );
insert into permissions (admin_id, org_id, obj, perm)
          select 1,  0,  obj, 'W' from objects
union all select 1, 22, 'O3', 'R'
union all select 1,221, 'O5', 'R'
union all select 1,221, 'O5', 'N';

在测试设置之后,一个选项如下:

/* without pivot */
;with cte as (
select
        p.parentid
      , p.id
      , step=0
  from org p
  where p.id = 2212
union all
select
       c.parentid
     , c.id
     , step=p.step+1
  from org as c
    inner join cte p on p.parentid = c.id
)
select o.obj, x.perm
  from objects o
    cross apply (
      select top 1 
          perm.perm
        from cte
          inner join permissions perm on cte.id = perm.org_id 
            and perm.admin_id = 1
        where perm.obj = o.obj
        order by step
    ) as x

没有支点的结果:

+-----+------+
| obj | perm |
+-----+------+
| O1  | W    |
| O2  | W    |
| O3  | R    |
| O4  | W    |
| O5  | R    |
+-----+------+

如果您需要将结果作为一行,则可以旋转上一个查询的结果:

/* with pivot */
;with cte as (
select
      p.parentid
    , p.id
    , step=0
  from org p
  where p.id = 2212
union all
select 
     c.parentid
    , c.id
    , step=p.step+1
  from org as c
    inner join cte p on p.parentid = c.id
)
select o.obj, x.perm
  from objects o
    cross apply (
      select top 1 
          perm.perm
        from cte
          inner join permissions perm on cte.id = perm.org_id 
            and perm.admin_id = 1
        where perm.obj = o.obj
        order by step
    ) as x
    pivot (min(perm) for [obj] in ([o1],[o2],[o3],[o4],[o5])) as p

带有支点的结果:

+----+----+----+----+----+
| o1 | o2 | o3 | o4 | o5 |
+----+----+----+----+----+
| W  | W  | R  | W  | R  |
+----+----+----+----+----+