12.采用左右值编码来存储无限分级树形结构的数据库表设计[摘自网络]
上一篇 / 下一篇 2008-05-05 10:42:03 / 个人分类:::方法类::
摘子:http://blog.csdn.net/comiunknown/archive/2007/04/26/1586020.aspx
之前我介绍过一种按位数编码保存树形结构数据的表设计方法,详情见:
;dkrj7@
a8U2G9T0 浅谈数据库设计技巧(上)
该设计方案的优点是:只用一条查询语句即可得到某个根节点及其所有子孙节点的先序遍历。由于消除了递归,在数据记录量较大时,可以大大提高列表效率。但是,这种编码方案由于层信息位数的限制,限制了每层能所允许的最大子节点数量及最大层数。同时,在添加新节点的时候必须先计算新节点的位置是否超过最大限制。
上面的设计方案必须预先设定类别树的最大层数以及最大子节点数,不是无限分级,在某些场合并不能采用,那么还有更完美的解决方案吗?通过 google的搜索,我又探索到一种全新的无递归查询,无限分级的编码方案——左右值。原文的程序代码是用php写的,但是通过仔细阅读其数据库表设计说明及相关的sql语句,我彻底弄懂了这种巧妙的设计思路,并在这种设计中新增了删除节点,同层平移的需求(原文只提供了列表及插入子节点的sql语句)。
下面我力图用比较简短的文字,少量图表,及相关核心sql语句来描述这种设计方案:
首先,我们弄一棵树作为例子:
商品
xG6l+d
K;D;q^2i0|---食品ITPUB个人空间}L9H5if;s$@
| |---肉类
L2q5WTDLL|0| | |--猪肉ITPUB个人空间"m4z n:C/S
| |---蔬菜类
h1VbB`%j0| |--白菜
u;ZF*~Ku0|---电器ITPUB个人空间0]E_7Adz
|--电视机
!Z.DR+PQ5dA H0 |--电冰箱
Type_id | Name | Lft | Rgt |
1 | 商品 | 1 | 18 |
2 | 食品 | 2 | 11 |
3 | 肉类 | 3 | 6 |
4 | 猪肉 | 4 | 5 |
5 | 蔬菜类 | 7 | 10 |
6 | 白菜 | 8 | 9 |
7 | 电器 | 12 | 17 |
8 | 电视机 | 13 | 14 |
9 | 电冰箱 | 15 | 16 |
SkOM j4y}i8I0 +-----------------+ +---------------------+
-rJ xfLmJ b AW0 3肉类6 7蔬菜类10 13电视机14 15电冰箱16
~h7xI?4I^v7~0 4猪肉5 8白菜9
Type_id | Name | Lft | Rgt |
2 | 食品 | 2 | 11 |
3 | 肉类 | 3 | 6 |
4 | 猪肉 | 4 | 5 |
5 | 蔬菜类 | 7 | 10 |
6 | 白菜 | 8 | 9 |
IS'b}s1N |]0
( u7b9wnF|^p0
@type_id int-a;k3pV0r"xAp0
)ITPUB个人空间o)r,`)GL_{4|
RETURNS intITPUB个人空间4Y jq1m:N#ZKU
ASITPUB个人空间+\3E,d)[6z!lB+h
beginITPUB个人空间gU?`mV T
}
declare @result int2b~ i%^;T:w D l-Z0
set @result=0_x G Y3f5j5A_0
declare @lft int+x XK3[wW%dW5kr0
declare @rgt intITPUB个人空间A*C LpO!SO
if exists (select 1 from tree where type_id=@type_id)G9yf9bE0S0
beginITPUB个人空间5`zWp'HR"J
select @lft=lft,@rgt=rgt from tree where type_id=@type_idITPUB个人空间9BT-P+~9lk'D/Q%T
select @result = count(*) from tree where lft <= @lft and rgt >= @rgtgL'V}v2mq ~0
end +Hus!A'Z4Vb0
return @result9?F6["@8o.KF8NPP0
endITPUB个人空间H
LQb(L7R2e
GOITPUB个人空间I"xP F#b$Pd
CREATE VIEW dbo.TreeViewITPUB个人空间R*r f$d.t]_&J
ASITPUB个人空间[?cw)y+T&V
SELECT type_id, name, lft, rgt, dbo.CountLayer(type_id) AS layer FROM dbo.tree ORDER BY lft#@.@N!b%x DF:E#Fh{Y0
GOIo/Fqhxx0
(