樹型結構在我們應用程式中還是很常見的,例如檔案目錄,BBS,權限設置,部門設定等。這些
資料
資訊都採用層次型結構,而在我們現在的關聯式資料庫中很難清淅表達。那麼要在程式中遇到樹型
結構問題該如何處理呢?
最近筆者透過一個ASP權限管理的程序輕鬆解決了一這問題,現在將其整理出來以颯讀者。
首先,要將層次型資料模型轉換為關係型資料模型。也就是說如何在我們的ACCESS,SQL SERVER
,ORACLE等關係型資料庫中設計這個資料結構。
拿個實例來講吧,譬如下面一個資料:
文件管理1
|----新建文檔2
|----文檔修改3
|----文檔歸檔4
| |----查看歸檔資訊5
| |----刪除歸檔資訊6
| | |----刪除歷史文檔7
| | |----刪除正式文檔8
|----系統管理9
|----用戶管理10
人事管理11
行政管理12
財務管理13
這是一個很典型的層次型結構數據,那麼大家想一想,如何將其透過二維表的形式來表達呢?初
看上去很難,對吧。可是仔細推敲一番還是有門路可鑽的。
可以這樣,將上面所有的權限視為一個權限字段,那麼這個權限字段肯定是要有ID值的。
我們
再給這個關係型資料表再強行加一個字段-隸屬ID字段,也就是表示這個權限是屬於哪一級權限
之下的,也就是這個ID值隸屬於哪一個ID值。例如:「檢視歸檔資訊」權限ID值為「5」,它是隸屬於「
文件
歸檔」權限之下的,那麼它的隸屬ID欄位的值就應該是「4」。OK,如果這一點能理解的話,那麼
我們
的關係轉化工作也就算基本上完成了。下面我們就開始設計這張關係型資料表(以Sql Server 7.0 為例):
+-----------+-----------+----- ------+-----------+----------+
| 欄位名稱| 欄位意義| 欄位類型| 欄位大小| 欄位屬性|
+-----------+-----------+-----------+-----------+- ---------+
| SelfID | 權限ID | Int | 4 | PK |
| PowerName | 權限名稱| Varchar | 50 | Not Null |
| PowerInfo | 權限資訊| Varchar | 500 | |
| BelongID | 隸屬ID | Int | 4 | |
+-----------+-----------+-----------+-----------+- ---------+
好了,結構設計好你就可以輕鬆輸入你的測試資料了。
然後,我們就針對如何在網頁中模仿層次結構顯示此功能的ASP程序,這也是最關鍵的一步了。
程式清單:powerlist.asp
<%
'資料庫連接
set conn=Server.CreateObject("ADODB.Connection")
conn.open "driver={SQL Server};server=chaiwei;DATABASE=chaiwei;UID=sa;PWD="
'開啟所有父層數據
set rs=Server.CreateObject("ADODB.Recordset")
rs.Open "select * from powers where belongid is null order by powerid",conn,1,3
'層次數表態變數賦初值
format_i=1
'列表主程式段
do while not rs.eof
'列印父層資料訊息
response.write "<a href='powerlist.asp?SelfID=" & rs("powerid") & "&BelongID=" & rs("belongid") & "'>" & rs("powername") & "< /a>"
response.write "<br>"
'子程序調用,子層資料處理
Call ListSubPower(rs("powerid"))
rs.movenext
loop
'關閉父層資料集
rs.close
set rs=nothing
'子層資料處理子程序
Sub ListSubPower(id)
'開啟隸屬於上層powerid 的所有子層資料資訊
set rs_sub=Server.CreateObject("ADODB.Recordset")
rs_sub.Open "select * from powers where belongid=" & id & " order by powerid",conn,1,3
'列子層數據
do while not rs_sub.eof
'層次數表態變數遞進累加
format_i=format_i+1
'循環縮排格式控制,因為頂層與二層不需要縮進,所以從第三層開始引用此程式段
for i=format_i to 3 step -1
response.write " |"
response.write " "
next
'列印子層資料訊息
response.write " |----"
response.write "<a href='powerlist.asp?SelfID=" & rs_sub("powerid") & "&BelongID=" & rs_sub("belongid") &"'>" & rs_sub("powername") & "< /a>"
response.write "<br>"
'遞歸呼叫子程式本身,對子層資料進行逐漸處理
ListSubPower(rs_sub("powerid"))
rs_sub.movenext
loop
'層次數表態變數遞退累減
format_i=format_i-1
'關閉子層資料集
rs_sub.close
set rs_sub=nothing
End Sub
%>
powerlist.asp程式中,我們先開啟頂層數據,在循環中顯示出來;然後又設計一個子程式ListSubPower,透過遞歸演算法在循環中調用,以此來開啟子層資料訊息,並且在子程序內部循環中反覆調用自己,以此來逐層展開深層資料。
另外,程式中也用了一個靜態變數format_i來控制縮排顯示格式。
本文就樹型結構在資料設計、程式控制上做簡單嘗試,目的在於拋磚引玉,希望讀者透過本文得到更多啟示。