文字是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,仍是某客戶的系統,用戶須要把數據提交給數據所在區域的上一級區域的領導。這樣,咱們就能夠先找到這條數據的區域,而後在去找父級區域,再到配置表中找對應的區域的角色。在測試中,不生效,可能系統不允許查詢區域表,也有多是生成腳本不支持而已,我會繼續測試。
爲何要去研究系統的權限,有什麼做用?
可能你們未必會看,並且我水平有限,你們也未必看明白了。咱們如今對標準功能愈來愈熟悉了,但是我想知其然,還要知其因此然。瞭解系統設計對咱們理解系統的運做,理解系統的業務有比較大做用。對於遇到須要跳出系統標準功能來設計系統的時候,咱們知道了系統的設計就不會那麼的茫然,最起碼能夠下降風險。