如何将树形结构对映到关系数据库中?

imafool 2003-09-19 10:29:42
一个树形数据结构,树枝的节点数和树的层次均是不确定的,树枝和叶子的均赋予属性值,并且对映地,存在一些数据记录拥有这些属性,而且属性的分解边界是模糊的(一条记录可能既属于A叶子,又属于B叶子)。一个相似的例子就是这个论坛左边的树形菜单。为了实现它的动态维护和在各个层次上查询,现在决定:把这些数据存储到SQL这种关系型的数据库中(使用SQL Server 2000)。

问题:如何来设计数据库?

前提和要求:
1、通过读取数据库动态的生成这个树形菜单。
2、用户可以在各个层次上查询。(比如在这儿的菜单中,点击左边的“MS-SQL Server 2000”,右边页面出来的内容涵盖所有四个子类,而点击“基础类”,则右边页面出现属于“基础类”的内容。)
3、记录属性有交叉,比如:一个名为“请教高手如何生成菜单”的贴子拥有在数据库区中“基础类”的类属,又拥有在WEB开发中的“ASP”的类属。用户直接输入进行查询时可以确定或者不确定操作所在的层次。
4、事实上树的高度不会超出5层。
5、只使用MS-SQL 2000数据库来记录数据,不使用其它方式。(如XML或文本文件)
6、您可以按您的经验给出一个折中的解决方法。适度改变需求(如:要求用户查询时指定针对的分类。)
7、如有未明之处请提出。
...全文
130 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
snowolf_ren 2003-11-25
  • 打赏
  • 举报
回复
Mark
pengdali 2003-11-24
  • 打赏
  • 举报
回复
为了效率建议你改表结构为:

tablename
id name .........
001 xxx .........
001001 yyy ........
002 uu .......
002002 yyyy ........


这样在存储上不如上面的省空间,但效率是sqlserver中最高的。代码也是最容易写的。
imafool 2003-11-24
  • 打赏
  • 举报
回复
结论:无新解。
CrazyFor 2003-09-19
  • 打赏
  • 举报
回复
化解32层以上嵌套,树型结构的递归实现方法,给大家参考一下!
http://expert.csdn.net/Expert/topic/1375/1375432.xml?temp=.8570978
imafool 2003-09-19
  • 打赏
  • 举报
回复
大力:

分类不是稳定的,也就是说随时会增删。比如,今天删了中国这个类,明天又加上,或者改了或什么的。
imafool 2003-09-19
  • 打赏
  • 举报
回复
谢谢。

但问题是我不仅仅是要存储一个树形数据而己,在另外的数据里还要标志它所属的分类。比如一个贴子,如果属于“基础类”,那么在“MS-SQL Server”中可以找到它,在“数据库开发”中也可以找到它。
还有,就是一个子可能不只一个父。有点象UNIX里的文件,可以同时属于两个不同路每径的目录。在查询时也要都能找到。
而且查询是针对“另外的数据”的,比如这里举例的贴子、文件。

还有,大家对效率将有何预测?

再次感谢。
pengdali 2003-09-19
  • 打赏
  • 举报
回复
/*--按父找子--*/
declare @a table (TC_Id int,TC_PID int,TC_Name varchar(200))
insert @a values(1,0,'中国')
insert @a values(2,0,'美国')
insert @a values(3,0,'加拿大')
insert @a values(4,1,'北京')
insert @a values(5,1,'上海')
insert @a values(6,1,'江苏')
insert @a values(7,6,'苏州')
insert @a values(8,7,'常熟')
insert @a values(9,6,'南京')
insert @a values(10,6,'无锡')
insert @a values(11,2,'纽约')
insert @a values(12,2,'旧金山')

declare @tmp1 table (TC_Id int,TC_PID int,TC_Name varchar(200),lev int)
insert @tmp1 select *,1 from @a where tc_ID=1
while exists(select 1 from @a a,@tmp1 b where a.tc_pid=b.tc_ID and a.tc_ID not in (select tc_ID from @tmp1))
insert @tmp1 select a.*,1 from @a a,@tmp1 b where a.tc_pid=b.tc_ID and a.tc_ID not in (select tc_ID from @tmp1)
select * from @tmp1
yujohny 2003-09-19
  • 打赏
  • 举报
回复
我树的结构数据库中的表一般如下设计:
ID 编号 名称 父ID 层次编码
数据举例如下
1 001 MS SQL SERVER 0 →1→
2 002 基础类 1 →1→2→
3 003 非技术版 1 →1→3→
4 004 开发语言 0 →4→
5 005 Delphi 4 →4→5→
6 006 Java 4 →4→6→

层次编码用触发器里生成,这样像SQL这样点父层时候包括下层的数据就好做了
imafool 2003-09-19
  • 打赏
  • 举报
回复
……其实呢,我将最终在网站页面上使用。

34,874

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧