SQL Server 儲存層級資料實現無限級分類

2021-04-22 00:07:26 字數 2608 閱讀 7190

sql server 儲存層級資料實現無限級分類

由於資料庫儲存的資料都是以平面方式儲存,所以目前大部分論壇和其他程式都是用遞迴來展現層次資料的,如果分類的層次十分深的話那麼使用的遞迴次數相當可觀,對效能的影響也非常大。最近要做乙個分類資訊的平台就遇到這個問題了,那麼如何實現快速的展現分層資料呢?mysql 的開發者幫我們想到了乙個演算法

,這個演算法目前唯一的問題就是尚未實現分類排序,我們可以通過右值的反向排序實現先入先出的排序。在這裡我們需要了解的是如何用 sql server 來實現,我們就以省市縣資料庫為例來實現:

如圖所示我們將乙個樹節點的左右各編上號碼,就可以看出一些規律,山西的左右值為(8,17),那麼所有左值大於8,右值小於17的節點都是屬於山西的子節點。稷山先的左右值為(14,15),那麼他的所有父節點就是左值小於14,右值大於15的節點,怎麼樣,用這個方法實現的無限級分類效能絕對是頂呱呱的。一次查詢就可以查出屬於某個節點的資料以及他子節點的資料。這個算是我見過效能最高的無限級分類演算法。其他演算法跟這個對比基本沒有任何優勢。

我們先建立乙個資料表,結構如下圖(lid 為左值,rid 為右值,tree 為節點深度,name 和 id 就不多說了,節點的索引和名稱)

我們可以使用下面的儲存過程來獲得乙個節點和其子節點:

create

procedure clsp_zoneselect  

(  @root int,  

@tree int

)  as

select z.id,z.tree,z.name

from cl_zonedata as z,cl_zonedata as p  

where   p.id = @root  

and z.lid >= p.lid and z.rid <= p.rid  

and (@tree = 0 or z.tree <= p.tree + @tree)  

order

by z.lid asc

go

我們可以用下面這個儲存過程來在乙個節點下插入新的子節點:

create

procedure clsp_zoneinsert  

(  @root int,  

@name nvarchar(50)  

)  as

declare @rid as

int,@nid as

int,@tree as

intset @rid = 1  

set @nid = 0  

set @tree = 1  

if @root = 0  

begin

select

top 1 @rid = rid + 1  

from cl_catedata order

by rid desc

endelse

begin

select @rid = rid, @tree = tree + 1  

from cl_zonedata where id = @root  

endif @root = 0 or @rid > 1  

begin

update cl_zonedata set rid = rid + 2 where rid >= @rid  

update cl_zonedata set lid = lid + 2 where lid > @rid  

insert

into cl_zonedata(lid,rid,tree,name)  

values (@rid,@rid + 1,@tree,@name)  

set @nid = scope_identity()  

endselect @nid  

go

刪除乙個節點可以用下面的儲存過程:

create

procedure clsp_zonedelete  

(  @id int

)   

asdeclare @lid as

int, @rid as

int, @wid as

int, @did as

intset @did = 0  

select @did = id, @lid = lid, @rid = rid, @wid = rid - lid + 1 from cl_zonedata where id = @id  

if @did != 0  

begin

delete

from cl_zonedata where lid between @lid and @rid  

update cl_zonedata set rid = rid - @wid where rid > @rid  

update cl_zonedata set lid = lid - @wid where lid > @rid  

endselect @did  

go  

這個方法,節點排序已經可以了。節點移動比較麻煩,不過可以曲線救國,在需要移動到的節點建立乙個新的。然後把子節點和資料都移動過去,再刪除現有的節點。

引用:http://www.loveyuki.com/article/104/trackback.ashx

Php無限層級,並顯示層級數

這裡的arr是直接從資料庫取出的,僅作為測試資料 arr array array id 1,name 一級選單a pid 0 pid 父級id array id 2,name 一級選單b pid 0 array id 3,name 二級選單a pid 1 array id 4,name 二級選單b ...

MySQL MySQL層級資料的遞迴遍歷

層級的業務資料在系統中很常見,如組織機構 商品品類等。如果要獲取層級資料的全路徑,除了快取起來,就是遞迴訪問的方式了 將層級資料快取在redis中,用redis遞迴獲取層級結構。此方法效率高。在mysql中做遞迴遍歷,oracle有遞迴的語法支援,而mysql並沒有 需要自己寫函式去遞迴。此方法效率...

SQLServer恢復表級資料

原文 sqlserver恢復表級資料 最近幾天,公司的技術維護人員頻繁讓我恢復資料庫,因為他們總是少了where條件,導致update delete出現了無法恢復的後果,加上那些庫都是幾十g。恢復起來少說也要十幾分鐘。為此,找了一些資料和工作總結,給出一下幾個方法,用於快速恢復表,而不是庫,但是切記...