文字是11年写的,贴出来共享一下,先来一张表结构图:sql
1、区域。表名:【territories】数据库
一、咱们先来看看区域表的结构。app
从图中前面都是不能为空的字段,都是很重要的。来介绍一下这些字段:ide
Terr_territoryid: 这个字段就是区域码测试
Terr_DBID:因为上面这个字段用来保存区域码了,因此用这个来作表的idspa
Terr_Caption:区域码的中文名称,咱们新建区域,只须要输入这个就能够了。翻译
Terr_ParentID:父区域的区域码。若是是根区域的话,父区域为空。设计
Terr_RangeEnd:区域的范围码。具体含义下面会介绍。blog
Terr_NextRangeStart:下一个子区域的区域码ip
Terr_ChildCount:该区域的直接子区域个数
Terr_Depth:该区域在区域树中的层数。
二、系统对区域码的分配机制(如下讲解都是在系统默认状况下的)
在进一步解释新建区域,系统往区域表插入记录以前,必须先讲讲系统对区域码的分配机制,这样咱们才能更加明白,系统对这个区域表的设计。
下面的内容比较理论,文件比较多,有兴趣的话,慢慢看就明白了。
1) 从表的结构咱们能够看到区域码的数据类型是整型的。数据库中int 类型的大小范围是:-2147483648至2147483647。他们的总和恰好是2的32次方。
2) 系统在默认状况下是这样设置区域的:
A,顶级区域的区域码确定是:-2147483640 ,因此只要大于这个数的区域都是他的子区域。
B, 系统会默认每一个区域的子区域都是2的4次方个,即16个。这样的话,让咱们看看咱们的系统最终区域的划分结果:
一,2 - 28 【268435454】
2、2 - 24 【16777216】
3、2 - 20 【1048576】
4、2 - 16 【65536】
5、2 - 12 【4096】
6、2 - 8 【256】
7、2 - 4 【16】
一表示第一个级子区域,他的上面就是顶级区域了。2的32次方分为16个子区域以后,每一个子区域的范围就是2的28次方,也就是 268435454。这样一直递减。
C,上面的分析,咱们知道咱们的系统一共能够分为8个级别,每一个级别(顶级除外)能够有16个区域。16的8次方就是 2的32次方了。
3) C、看到这里,咱们会问两个问题:为何是默认16呢?若是个人子公司不止16个或者咱们的级别不止8个呢?
问题1:首先,16恰好是2的倍数,容易计算和划分,能够最大限度的利用区域码,其次,我以为16 对于二进制的装换有优点。这些是我我的的见解而已。多是错的。
问题2:当出现这种状况的时候,新建第15或者16个子区域的时候,系统会提示咱们先平衡区域。我在252的crm 数据库作了一次平衡。一共有95步,可能咱们的表太多了。平衡的过程其实就是在从新选一个基数,扩大了子区域个数表大以后,级别的就会表小,调整以后,还要修复已有数据的区域码。 其实通常的公司是很难达到这个数的。例如咱们的国家:国家-省-市-县-镇-乡 也才六个级别。假设每一个省下面也是23个市。 23 的 6次方也没有大于2的32次方。
3,数据库的设计方面
有了上面的机制以后,再来看看数据库表现。
如图,
a) worldwide这个是顶级区域,因此他的父区域为0。而E总部的terr_parentid 就是 worldwide的区域码了。新建区域的时候系统会要求咱们选择一个父区域的。
b)Terr_RangeEnd这个字段的值就是Terr_territoryid + 这个级别的区间的范围基数了。
l 顶级区域固然是最大的区间 为-2147483648 + 2的32次方 = 2147483647
l E总部是二级区域因此 是 -1342177274 + 2的28次方 = -1073741820
l …………..
l 因此咱们能够理解为:全部本身的子区域都是在 [Terr_territoryid,Terr_RangeEnd] 这两个字段组成的区间以内的。
c) terr_caption 是新建时候的翻译而已,很少说。
d)Terr_nextRangeStart 这个字段的意思是下一个子区域的区域码,例如worldwide 只有一个子区域E总部,因此咱们新建一个E总部的同级区域时,这个新区域的区域码就是-805306364了。原本子区域的第一个区域的区域码应该是父区域码加1的,因为咱们的E总部是在之前的基础上删改的,因此…。从留学中心以后你就能够看到了。Terr_nextRangeStart 这个字段不但告诉咱们下一个子区域的区域码,同时也是告诉咱们本区域内的范围的区间能够缩小为:[Terr_territoryid,Terr_NextRangeStart]。
e)Terr_ChildCount:该区域的直接子区域个数。留学中心暂时有13个分公司,因此他的直接子区域是13
f)Terr_Depth:该区域在区域树中的层数。留学中心在第三层,可是数据库从0开始,因此显示为2。
g)这里还有一个字段要讲一下的:terr_rangeincrement,这个字段记录着子区域的 范围基数如图:
2、配置文件 【TerritoryProfiles】
只保存了基本信息而已。主要的配置信息保存在表【TerritoryPermissions】
三.配置信息【TerritoryPermissions】
这个配置表中保存了咱们新建的配置文件的信息和直接权限的信息。每一个配置文件,每一个区域都会把全部的主要实体列出来给咱们设置。 配置文件、区域和表就关联起来了。
直接权限也同样,要求咱们要选一个区域,而后才添加用户到这个区域,再设置表的权限。
直接权限和配置表的数据的区别就在于 usrt_userid 和 usrt_profileid。usrt_userid不为空就是直接权限的数据。usrt_profileid不为空就是配置文件。
四,使用实例
当用户到机会模板的高级查找查询数据时:
系统首先会找到登陆用户的id 和 用户表里面的 配置配置文件id。
而后到这个视图去找登陆用户的权限:
select * from dbo.vTerritoryPermissions where (usrt_userid = 630 or usrt_profileid = 10) and bord_tableid = 10167
上图显示了查询结果是我在配置表中的一个直接权限 和 配置文件签约顾问或客服中的四个区域的权限。
而后在去找机会表过滤数据。
五,权限的一些特殊应用例子
1,在某客户的系统的管道图,因为管道图的sql 语句要用到group by 因此标准的findrecord知足不了,因此出现了管道图中的数据和列表的数据不一至。我是这样作的:先用findrecord找出数据,而后把这些数据的id打包起来放到管道图中sql 语句中限制范围。
2,仍是某客户的系统,用户须要把数据提交给数据所在区域的上一级区域的领导。这样,咱们就能够先找到这条数据的区域,而后在去找父级区域,再到配置表中找对应的区域的角色。在测试中,不生效,可能系统不允许查询区域表,也有多是生成脚本不支持而已,我会继续测试。
为何要去研究系统的权限,有什么做用?
可能你们未必会看,并且我水平有限,你们也未必看明白了。咱们如今对标准功能愈来愈熟悉了,但是我想知其然,还要知其因此然。了解系统设计对咱们理解系统的运做,理解系统的业务有比较大做用。对于遇到须要跳出系统标准功能来设计系统的时候,咱们知道了系统的设计就不会那么的茫然,最起码能够下降风险。