閉包錶是解決分層儲存乙個簡單而又優雅的解決方案,它記錄了表中所有的節點關係,並不僅僅是直接的父子關係。
在閉包錶的設計中,額外建立了一張節點關係表(空間換取時間),它包含兩列,每一列都是乙個指向樹形結構中主鍵的外來鍵。這張表存放包括自身在內的所有的和他有關係的節點資料
create
table comments(
commentid int pk,
articleid int
, commentbody int
,foreign
key(articleid)
references articles(id)
)
create
table treepaths(
ancestor int
, descendant int
,primary
key(ancestor,descendant)
,--復合主鍵
foreign
key(ancestor)
references comments(commentid)
,foreign
key(descendant)
references comments(commentid)
)
在這種設計中,comments表將不再儲存樹結構,而是將書中的祖先-後代關係儲存為treepaths的一行,即使這兩個節點之間不是直接的父子關係;同時還增加一行指向節點自己,理解不了?就是treepaths表儲存了所有祖先-後代的關係的記錄。如下圖:
comment表:
treepaths表:
優點:1、查詢所有後代節點(查子樹):
select c.
*from
comment
as c
inner
join treepaths t on c.commentid = t.descendant
where t.ancestor =
4
結果如下:
6顯示結果如下:
3、插入新節點:
insert
into treepaths(ancestor,descendant)
select t.ancestor,
8from treepaths as t
where t.descendant =
5union
allselect8,
8
執行以後:
至於comment表那就簡單得不說了。
4、刪除葉子節點:
比如刪除葉子節點7,應刪除所有treepaths表中後代為7的行:
delete
from treepaths where descendant =
7
5、刪除子樹:
delete from treepaths
where descendant
in(select descendant from treepaths where ancestor = 4)
另外,移動節點,先斷開與原祖先的關係,然後與新節點建立關係的sql語句都不難寫。
另外,閉包錶還可以優化,如增加乙個path_length欄位,自我引用為0,直接子節點為1,再一下層為2,一次類推,查詢直接自子節點就變得很簡單。
樹形結構資料儲存方案之閉包錶
待本人專案完成奉上自己的專案流程及資料庫設計。將closure table翻譯成閉包錶不知道是否合適,閉包錶的思路和物化路徑差不多,都是空間換時間,closure table,一種更為徹底的全路徑結構,分別記錄路徑上相關結點的全展開形式。能明晰任意兩結點關係而無須多餘查詢,級聯刪除和結點移動也很方便...
閉包和物件導向設計
物件以方法的形式包含了過程,而閉包則是在過程中以環境的形式包含了資料。通常用物件導向思想能實現的功能,用閉包也能實現。var extent function var extent extent extent.call 輸出 1 extent.call 輸出 2 extent.call 輸出 3換成物...
資料庫 閉包錶
一 精英 晶 1 閉包錶中設計distance欄位,用於查詢指定節點指定子層級的所有子節點 2 可管理機構的查詢 合同專案的查詢 3 查詢所有的上級機構,hd group path 4 通過為指定資料庫使用者授權訪問表的許可權 5 oracle 授權sql方法 建立dblink create pub...