用户名: 密码: 免费注册 忘记密码? 加入收藏 | 设为首页
完整路径在树型结构表中的应用
学院首页 | 资讯中心 | 服务器软件 | 系统工具 | 系统软件 | 办公软件 | 聊天软件 | 多 媒 体 | 网页制作 | 网站运营 | 平面设计
艺术欣赏 | 数据库软件 | 程序开发 | 网络组建 | 源码下载 | 驱动下载 | 软件下载 | 电脑安全 | IT创业 | IT博客 | IT社区
硬件数码导航 | 硬件频道 | 本本频道 | MP3频道 | 相机频道 | 手机频道 | 显卡频道 | LCD 频道 | 音箱音频 | 行情 | 评测 | 导购
学院专题 软件 - 系统 - 办公 - 聊天 - 多媒体 - 网页制作 - IT创业 - 运营 - 平面 - 设计欣赏 - 数据库 - 程序 - 服务器 - 组网

 当前位置: 首页>>技术频道>>数据库>>Oracle教程>>正文

完整路径在树型结构表中的应用

日期:2006-9-15 4:11:41     来源:csdn   编辑:   

    在MIS系统开发过程中经常使用树型结构表,如人力资源模块的部门表、财务模块的会计科目表等,传统的做法是从编码上体现一种树型父子关系,并约定每节的字长,这种做法强制用户按照程序既定的规则,用户没有选择编码规则的自由,扩展性差 。 为了解决这个问题,一般会在表中建两个栏位(或类似栏位):id和parent_id,用于表述两条数据间的树型父子关系,但这带来的负作用是查询非直接父项或子项时需要使用递归算法或循环,性能上并不令人满意 。 如果在此基础上增加一个完整路径的栏位(能够完整描述一个项目的路径的栏位,类似操作系统的文件全路径),则查询性能会明显提高 。


我们以一个部门表为例 。
CREATE TABLE [hrm_dept] (
[dept_code] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[dept_name] [varchar] (40) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[parent_dept_code] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL,
[dept_path] [varchar] (8000) COLLATE Chinese_PRC_CI_AS NULL ,
CONSTRAINT [PK_hrm_dept] PRIMARY KEY CLUSTERED

[dept_code]
) ON [PRIMARY]
) ON [PRIMARY]

其中:dept_code表示部门编号,dept_name表示部门名称,parent_dept_code表示父部门编号,dept_path表示部门路径(由触发器维护) 。
用户的需求是根据输入的部门编号获取该部门的所有子部门(直接和间接) 。
如果没有dept_path栏位或不利用dept_path栏位,我们所创建的获取指定部门的所有子部门的函数可能会这样写 。
CREATE FUNCTION udf_hrm_getchilddept (@dept_code varchar(20))
RETURNS @tab_childdept TABLE (parent_dept_code varchar(20),child_dept_code varchar(20))
AS
/*
名称: udf_hrm_getchilddept
功能描述: 取指定部门的所有子部门
涉及对象: hrm_dept 部门表
实现方法简述:递归取子部门
输入参数: @dept_code 部门编号
输出内容: 指定部门的所有子部门
创建人员: 康剑民
创建日期: 2006-06-06
*/
BEGIN
---定义临时表以存储子部门数据
declare @temp_childdept table
(row_id int IDENTITY(1, 1) not null
,parent_dept_code varchar(20) not null
,child_dept_code varchar(20) not null)

declare @child_dept_code varchar(20),--子部门编号
@max_row_id int,---
插入的最大行号
@loop_row_id int---循环行号

---插入直接子部门数据
insert into @tab_childdept
(parent_dept_code
,child_dept_code)
select @dept_code
,dept_code
from hrm_dept
where parent_dept_code = @dept_code

---插入直接子部门数据到临时表
insert into @temp_childdept
(parent_dept_code
,child_dept_code)
select @dept_code
,dept_code
from hrm_dept
where parent_dept_code = @dept_code

---取最大行号和最小行号
select @max_row_id = max(row_id),
@loop_row_id = min(row_id)
from @temp_childdept

if @loop_row_id is null or @loop_row_id = 0 select @loop_row_id=1
---循环取子部门数据
while @loop_row_id <= @max_row_id
begin
select @child_dept_code = child_dept_code
from @temp_childdept
where row_id = @loop_row_id

---插入子部门的子部门数据
insert into @tab_childdept
(parent_dept_code
,child_dept_code)
select parent_dept_code
,child_dept_code
from dbo.udf_hrm_getchilddept(@child_dept_code)

---
循环变量步进自增
select @loop_row_id = @loop_row_id + 1
end
return
end

如果使用部门路径栏位,则该函数可以按如下改造 。
CREATE FUNCTION udf_hrm_getchilddept2 (@dept_code varchar(20))
RETURNS @tab_childdept TABLE (parent_dept_code varchar(20),child_dept_code varchar(20))
AS
/*

名称: udf_hrm_getchilddept
功能描述: 取指定部门的所有子部门
涉及对象: hrm_dept 部门表
实现方法简述:根据部门路径取子部门
输入参数: @dept_code 部门编号
输出内容: 指定部门的所有子部门,返回表栏位含义:
parent_dept_code 父部门编号
child_dept_code 子部门编号
创建人员: 康剑民
创建日期: 2006-06-06
*/
BEGIN
declare @dept_path varchar(8000)--部门路径

--取部门路径
select @dept_path = dept_path
from hrm_dept
where dept_code = @dept_code
--插入子部门数据(直接和间接)
insert into @tab_childdept
(parent_dept_code
,child_dept_code)
select parent_dept_code
,dept_code
from hrm_dept
where dept_path like @dept_path + '/%'

在此我们假设dept_path使用’/’分隔部门编号 。
经测试,方法二明显性能提高 。 以笔者的测试样例数据,获取子部门数同样为727条,方法一需要3646毫秒,方法二只需要20毫秒,方法一所用时间是方法二的182倍 。 如果dept_path栏位长度可以控制在900个字节以内(MSSQLSERVER限制)并在其上加索引,则速度更快 。 注:不同的测试环境,样例测试数据可能不同,但结论是相同的,那就是方法二性能好 。
根据指定的项目取所有父项目的方法类似 。
当然,如果使用完整路径,应该在表的插入、修改、删除触发中维护完整路径的值,维护的代价不高,但查询速度得到大幅度提高,如果这个树型结构表不是频繁地插入、修改、删除数据而是查询的机会多的话,这种优化方法是值得去做的 。 另外还要注意几点:如果生成完整路径的字符过长,可以采用text类型;完整路径所依赖的栏位不能使用程序所使用的分隔符 。 gigi_miao
  ▼ 下一篇新闻 oracle-快速删除重复的记录
  ▲ 上一篇新闻 没有了        网友发表观点请进入=>



我要纠错】【进入论坛交流】【关闭此页

文章搜索
   
最新文章

 
·千名爱好者参与首届PHP调查
·腾讯称QQ通讯信息密钥加密 不会被
·雅虎反超Google排名搜索第二
·中搜等十余家IT企业因流氓软件被
·盛大前员工克隆网游装备获暴利被
·凤凰网将向迅雷提供娱乐及宽带内
·信产部出手规范 新浪式企业法律架
·雅虎中国称旗下软件早已没有流氓
·中搜停止划词搜索与流氓软件决裂

广告赞助
相关文章 相关教程下载
焦点信息
·腾讯称QQ通讯信息密钥加密 不会被监听
·信产部出手规范 新浪式企业法律架构不得不改
·盛大前员工克隆网游装备获暴利被追刑责
·凤凰网将向迅雷提供娱乐及宽带内容
·雅虎中国称旗下软件早已没有流氓问题
·雅虎反超Google排名搜索第二
网友评论:(评论内容只代表网友观点,与本站立场无关!)
发表评论     Hard168社区推荐帖子
姓 名: *
* 请网友遵纪守法并注意语言文明。
IT人物推荐

王江民
马云
柳传志



关于本站    联络方式    广告服务    意见信箱    加入收藏   设为首页    -
本站部分内容来自网上,如有侵权部分,敬请告知,我们会在24小时内给予处理
版权所有:Hard168.Com,如需转载文章请与我们取得联系
京ICP备05063857号 Designed by Hard168.Com
完整路径在树型结构表中的应用