web权限管理设计(1)——设计的要点分析(3)

接着上一篇,上面说了尽管继承会带来很多问题,但是依然需要使用。

为了使继承发挥好它的作用,而不是给我们带来更多困难,所以给管理者也提出要求。

就是设计角色的时候,要充分考虑一个角色所拥有的资源,是否具有一定的关联性。而不能随意将一些不相关的资源整合到一个角色中。因为这样会给后期的维护带来巨大的困难。

举个例子

比如说,在公司创立初期,总经理可能需要身兼数职,什么职员,会计,财务,总经理,全一人干了。在设置角色的时候,没有充分考虑以后,直接把财务和会计的权限做到了一个角色财务里面。然后总经理再继承这个角色。

而逐渐公司发展起来了,分别招了个会计和财务,这时候发现,如果给会计和财务直接继承原来的财务角色,那么就会给她们过大的权限。此时又需要重新设计角色。

所以从一开始就根据实际情况去设计好角色,后续的管理上就会省去很多事,上面的例子只是一个普通的事,有些情况可能比这复杂很多,后期再修改会很麻烦。

角色设计原则

  1. 根据实际业务场景,尽可能充分考虑未来有可能出现的情况,将角色设计的细化点
  2. 角色具有的权限,尽可能是高度相关的,不能图方便,将无关的权限放到一个角色里面
  3. 创建角色时务必描述清楚角色的意义和作用,因为创建者不一定是以后的管理者。不能保证以后的管理者还能理解该角色存在的意义
  4. 绝对不能出现继承环。很可能导致程序崩溃。

角色继承制度优化

为了优化查询的效率和防止继承环的出现,我还想到了一个方案。那就是角色id跟它的等级强相关,等级越高的角色,它的id值越大。

有了上面的约束,那么就可以直接防止继承环的出现,因为id小的不能继承id大的。

比如角色A继承自角色B,角色B继承自角色C,那么他们的id大小关系是A>B>C,那么在C想继承A时,就会发现,A的id比C大,不允许继承。从而避免了继承环的出现。

所以,角色id一定大于被他继承的角色,也一定小于继承他的角色

角色id设计

那么如何安排角色的id才能够让id满足上述要求呢?
首先,我们知道int32的值大概21亿,这已经是个天文数字,用它做角色的id,绝对足够了。那么怎么设计才能合理呢?

我们前面分析了,角色有了继承关系之后,是个复杂的链表,我简单画了个链表示意图:

在这里插入图片描述

从这个图中,可以看出来一点规律,最底层的A,他们没有从其他角色中继承,而第二层的BC,就是继承了一层。以此类推,他们的层级,就是从最底层算起,继承的层级越深,等级就越高。

那么就可以总结出第一条规律:最底层的角色,就是没有继承的,直接拥有资源。

再来分析下谁应该在最顶层呢?这个也很容易想到,超级管理员嘛。但是超级管理员是个特殊的存在,它不需要角色,任何的权限检查都会对它直接放行。那么下面可能还会需要普通管理员。所以,普通管理员就可以作为最顶层。·

麻烦的是中间层如何安排。因为角色不可能在一开始就完美的安排到位,是会面临增删改的。

总之,我们约定,层次越高的角色,id值越大

推演角色链表建立过程

假设,现在有了一个最底层角色A,然后还有一个管理员角色Z,那么按照角色A可以安排为id=1。管理员角色Z的id=21亿整。

现在,需要插入一个中间角色H,他们的关系是Z继承自H,H继承自A。那么这个H该安排一个什么样的id才合理呢?

需要考虑的点是:

  1. A和H之间,可能还会继续插入别的值
  2. Z和H之间,也可能会插入别的值
  3. A,H,Z都还可能会插入邻居

所以我们得给这些可能留有位置。

首先考虑最简单的第三点:给邻居留位置。那么每一层会有多少个角色呢?不知道,但是,我想再复杂的权限管理系统,一层的角色数,不能超过一万个吧?所以,我们就规定,为每一层留一万个位置。

那么我们可以有多少层呢?21亿除以一万等于21万。也就是说,我们这个复杂链表可以21万层。可以想象21万层有多高吗?所以,这个空间非常充足。

现在第三点解决了。再来看第一点和第二点,他们性质是一样的,所以解决方案也是一样的。

H是直接继承自A,A所在的层次id范围[0,9999]。那么H能不能直接设置为id=10000呢?答案肯定是不能的,因为没有给未来留足空间,但是我们又不知道A和H之间未来会插入多少层空间。所以,为了充足预留上下空间,我采用中间值法:

H介于A和Z中间,那么H所在的层次是:(21万+1)/2=105000层。所以H的id范围是[1050000000,1050009999]

看起来是有点夸张,直接就到10亿级别了。但是这是在无任何依据下,给未来留足空间的好方法。

其实也不用太担心空间浪费,其实都仅仅是一个数字而已,我们这个空间非常充足,能用完那是真厉害。

上面解决了最简单的一种情况,那么继续推演一下:

在已存在层次中添加角色

我要添加一个角色J,它继承自A。从上面分析,我们很容易知道,它和H位于同一层。可程序不像人,可以想象这个链表的结构。它并不知道已经有一个H存在,更不知道这个H和它有什么关系。其实这个好办:

select 角色id from 角色表 where 继承id between [0,9999]

用sql语句大概描述一下,就很清楚了,因为我们清楚的知道角色J继承的角色A处于什么层次,所以,如果有别的角色也继承自该层,那么就可以用语句查询到。然后就可以通过某种思路在同一层给他安排一个id。

添加新的层次角色

现在我要添加一个角色R,它继承自H,而角色Z继承自角色R。其实就和我们刚开始添加角色H一样,只不过是在H和Z之间找中间的那层去新建:(21万+105000)/2=157500层,所以角色R所在的id范围是[1575000000,1575009999]。

结论总结
  1. 角色的id:最底层从0开始,最高层从21亿开始。每层一万个位置,所以共计有21万层。
  2. 每次在一个新的层次增加,其id位于其继承者和被继承者的中间那一层。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值