大大毛 的筆記

            DDM's Note

          哪怕沒有辦法一定有說法,
          就算沒有鴿子一定有烏鴉,
          固執無罪 夢想有價,
          讓他們驚訝.

          posts - 14, comments - 23, trackbacks - 0, articles - 58
             :: 首頁 ::  :: 聯系 ::  :: 管理

          樹型結構的處理

          Posted on 2006-10-15 03:16 大大毛 閱讀(886) 評論(0)  編輯  收藏 所屬分類: SQL
          ???樹型結構在應用中被廣泛的運用,在數據操作上需要一定的技巧來進行處理:

          ???在表結構的定義上,有多種方式可以采用。
          ??.數據表:
          ??????a.單向鏈表式的結構 ( 這是藕給它起的名稱,因為它與鏈表的結構相似,除了必要的自身描述外,就只包含父節點的位置)
          ?????????DDL示例:
          --相當于單向鏈表
          create?table?linkTree?(
          ????id?
          varchar(10)?primary?key,?????????--節點自身ID
          ????nodeContent?varchar(50),??????????--節點內容
          ????parentId?varchar(10)?default?''????--父節點ID
          )

          ?????????優點
          ????????????.列寬固定,表結構易維護;
          ????????????.查找指定節點的上/下游節點效率高;
          ????????????.維護樹型結構方便(增/刪層);
          ?????????缺點,如在下列情況中,都需要多次Select完成:
          ????????????.從指定節點開始列出全部子樹 ( 除 Oracle 提供支持外 );
          ????????????.返回從指定節點A到其子節點B的路徑 ( B 與 A 的層數相差會大于 1 );

          ?????????DML示例:
          ????????????向下查找及統計子節點(僅一層)
          ????????????(1)通過父節點的ID
          通過父節點的ID

          ????????????(2)通過父節點的內容
          條件列nodeContent上存在唯一性約束

          ???????????????由于條件列無唯一性約束,所以在查找時有可能會返回一個記錄集,需要做一些處理:
          條件列nodeContent上無唯一性約束

          ????????????(3)查找兄弟節點
          查找兄弟節點

          ????????????(4)遍歷樹
          ????????????由于鏈表式表結構的特點,決定了無法用通用的單次 Select 完成操作,對于不同的 DBMS 可以采取不同的策略:
          ????????????如Oracle
          ???????????????select * from linkTree start with id='00' connect by PRIOR??id = parentId;
          ????????????如Ms-SQL2000
          ???????????????表的結構決定了數據只能逐層查找,網上常見的有使用存儲過程進行遞歸返回表變量來實現。
          ???????????????這里我用循環的方式來實現,效率比遞歸+表變量要高。
          Ms-SQL2000遍歷樹
          ??????注:這里引入一個site列,是為了能夠在輸出時更加好的進行排序,因為在最終輸出至網頁時很有可能是順序向下輸出的,這里正好體現出這種結構。

          ??????b.位置描述式的結構 ( 這是藕給它起的名稱,它有一個列,該列描述了當前節點在樹中的位置)
          ?????????DDL示例:
          create?table?siteTree?(
          ????id?
          varchar(2)?primary?key,
          ????nodeContent?
          varchar(20),
          ????site?
          varchar(200)
          )

          ?????????例子
          ????????????01??????Root??????01
          ????????????02??????dep1??????0102
          ????????????03??????dep2??????0103
          ????????????04??????dep11??? 010201

          ?????????優點
          ????????????由于該表結構中帶一個位置描述列site,因此對于關于樹的遍歷等問題的解決將變得異常的輕松。位置列按從根結點到當前結點的ID連接而成。

          ?????????缺點
          ????????????有利即有弊,位置描述列也同時突出該種結構的缺點,它最大的缺點就是樹的層次不可能是無窮的,由于它由整個路徑的ID連接而已,因此該列的寬度并不是固定的,如根節點的長度將是ID列的寬度,而當前節點位置列所需要空間 = 當前節點層次 * ID列寬度。
          ????????????針對鏈表式結構的優點,這里就成了缺點,層次間的增刪將變得較為困難。

          ?????????遍歷樹:
          --輸出指定節點的全部子節點
          select?*?from?siteTree?where?CHARINDEX('00',site)=1?order?by?site


          i am ddm

          主站蜘蛛池模板: 星座| 松溪县| 静海县| 沙河市| 达孜县| 隆林| 石门县| 厦门市| 双桥区| 津南区| 滕州市| 大港区| 周至县| 延吉市| 金山区| 南宫市| 惠安县| 上犹县| 衡南县| 同德县| 清远市| 阜南县| 封开县| 布拖县| 乐山市| 左贡县| 阿坝县| 栾川县| 东山县| 大厂| 汉阴县| 彝良县| 商水县| 金寨县| 南充市| 新源县| 潢川县| 日土县| 吴桥县| 泸定县| 九龙县|