[SQL Server]SQL Server中如何存儲具有層次關係的表(轉)

SQL Server是關係型數據庫,適合存儲二維表格的關係型數據,不適合存儲具有層次關係的數據,那麼如何利用SQL Server存儲如下圖所示的樹型層次關係呢?

 

目前利用SQL Server存儲樹型關係數據比較成熟的方案是利用主鍵+外鍵的方式,即主鍵存儲一個唯一Id值,外鍵存儲此Id的父節點Id值,如果此節點無父節點,則爲null。表設計如下:
Create Database TestDb;
go
use TestDb
go
Create Table EmployeeTable
(Id int primary key,
UserName nvarchar(32) not null ,
ParentId int null references EmployeeTable(Id),
)
go
下面爲表填充數據:
insert into EmployeeTable
    select 1,'項目經理',null union
    select 2,'技術經理',1 union
    select 3,'產品經理',1union
    select 4,'測試經理',1 union
    select 5,'技術組長1',2 union
    select 6,'技術組長2',2 union
    select 7,'測試員工1',4 union
    select 8,'技術員工1',5 union
    select 9,'技術員工2',5 union
    select 10,'技術員工3',5
go
select * from EmployeeTable
結果集爲:
Id    UserName    ParentId
1    項目經理    NULL
2    技術經理    1
3    產品經理    1
4    測試經理    1
5    技術組長1    2
6    技術組長2    2
7    測試員工1    4
8    技術員工1    5
9    技術員工2    5
10    技術員工3    5

可以看到,項目經理已經是最高級別了,所以它沒有父節點,相應的ParentId爲null。技術經理、產品經理、測試經理都是項目的子節點,所以它們的ParentId都爲1,1即是項目經理的Id。其它節點的插入規則類似。

樹型結構是存儲下來了,如何高效率的執行遞歸查詢呢?SQL Server 2005以後,提供了CTEs專門用於遞歸,下面結合上面的例子,給出查詢的SQL語句。

1.查詢技術組長1所有子節點的員工信息
with c as
(
    select * from EmployeeTable where [Id] = 5
    union all
    select a.* from EmployeeTable as a
    join c on a.ParentId = c.Id
)
select * from c

2.查詢技術組長1所有父節點的員工信息
with c as
(
    select * from EmployeeTable where [Id] = 5
    union all
    select a.* from EmployeeTable as a
    join c on a.Id = c.ParentId
)
select * from c

上述方法試用於SQL Server 2005以上的數據庫系統,如果您已經開始使用SQL Server2008了,那麼有個好消息要告訴您,從2008開始SQL Server提供了一個新的數據類型hierarchyid,專門用來操作層次型數據結構,hierarchyid相關內容請參考:


本文來自CSDN博客:http://blog.csdn.net/tjvictor/archive/2009/07/30/4395677.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章