關係型資料庫處理樹狀層級結構向來是棘手難題。SQL Server 2005 引入通用資料表運算式 (CTE) 緩解遞迴查詢,但仍屬查詢層面技巧。SQL Server 2008 推出 HierarchyId 原生資料類型,將層級結構提升為「頭等公民」,從儲存、索引、操作三個維度徹底重塑樹狀資料建模體驗。
傳統遞迴模型:每筆記錄僅存父節點參考(相對位置),修改父節點為原子操作,不影響子孫——但查詢全路徑需遞迴,效能差。
HierarchyId:單一欄位儲存節點在樹中的絕對路徑編碼。範例值:0x (根, "/")、0x58 ("/1/")、0x5AC0 ("/1/1/")。查詢祖先/後代、路徑比對、排序全變為索引可用的範圍操作,效能數量級提升。
| 方法 | 功能 | 備註 |
|---|---|---|
| GetAncestor(n) | 取得第 n 層祖先節點 | 樹向上遍歷 |
| GetDescendant(child1, child2) | 取得兩子節點間的插入位置 | 不返回既有子節點,返回「潛在插入槽」位置,插入新節點必須先呼叫此方法 |
| ToString() / Parse() | 二進位編碼 ⇄ 字串路徑 ("/1/2/") | 人類可讀與儲存互轉 |
| Read/Write (BinaryReader/Writer) | 串流序列化支援 | 應用層直接處理二進位流 |
修改父節點會導致整棵子樹的 HierarchyId 全部變更(路徑編碼包含父路徑)。Denny Cherry 與 Ravi S.Maniam 建議:父節點變動頻率低的場景最適合。若頻繁重組樹結構,傳統遞迴模型或物件化路徑可能更佳。
截至目前,缺乏成熟的「集合基礎」T-SQL 模式操作 HierarchyId 樹(如整棵子樹移動、批次重組)。現有操作更接近命令式程式設計。建議:
• 簡單查詢(祖先/後代/路徑)充分利用原生方法與索引
• 複雜重組邏輯封裝於 CLR 預存程序或應用層
• 結合 HIERARCHYID::GetRoot()、IsDescendantOf() 等靜態方法構建可維護的資料存取層
HierarchyId 為 SQL Server 帶來原生、高效能、可索引的樹狀建模能力,特別適合組織架構、產品分類、檔案系統、BOM 物料清單等「讀多寫少、結構相對穩定」的層級資料場景。正確理解其編碼語意與變更衝擊,是發揮最大效益的關鍵。