主题:  关于导航条的制做?<高手给分析一下这个bbs>

进军.net

职务:普通成员
等级:1
金币:0.0
发贴:105

进军.net

职务:普通成员
等级:1
金币:0.0
发贴:105
#22005/5/9 16:18:40
这个很经典,但有些地方我还是看不太懂!高手给分析一下吧!谢谢了



蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#32005/5/9 16:38:12
它的原理就是无限级分类法,依靠关系型数据库的内链接,确定表内记录之间的关系。
数据库可能为了查询高效,有些字段设计还是多余的,比如有parent就不必有child,因为这样有两个关系链就使数据库的关系复杂化了,使用一条链将更加清晰。
也许增加child是为了查询父关系的方便,在asp中可能这种做法还是值得,但如果用asp.net或asp的object可以生成树形结构,这样能描述完整的关系,或其中子树关系。这样设计,parent就显得多余了。我觉得数据库设计必须简洁,不必要的字段尽量不要设计,宁可用程序来完成,除非在性能上有很明显帮助。
同样描述字段,也只一个就够了,不必描述父类或子类的描述,这些完全可以用程序或查询达到效果。数据库复杂了,在维护数据库时或增删时增加复杂度了。

编辑历史:[此帖最近一次被 蓝鲸 编辑过(编辑时间:2005-05-09 17:00:10)]

非常大鱼

进军.net

职务:普通成员
等级:1
金币:0.0
发贴:105
#42005/5/9 16:48:06
版主你三言两语讲完了,可我还是不懂呀!那位能不能把代码分别给列一下,我看不出来,调试了半天也不行:

像这样:

1.asp
代码....

2.asp
代码....

3.asp
代码....



缺缺

职务:管理员
等级:8
金币:41.0
发贴:9620
#52005/5/9 16:54:41
明白思路才可以
在项目中经常会碰到无限级分类的应用,了解其原理才是最重要的,而不是所要代码.对于一个项目,思路结构来决定代码

对于级别比较简单的,比如这个论坛的主题列表,只要根据当前板块ID查询数据库得到名称就可以.如果不是最顶级,就继续查询父级别的名称.其实是一个递归的过程.



蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#62005/5/9 17:25:39
它好象是用childdir和parentdir分别表示父目录和子目录,但好象觉得这样只能有一个子目录了,不能有多个,是否是这样设计?
另外这个设计还有个问题,比如music这个字段要改成mp3或其它,那么所有的music都需要修改,是否很麻烦?
也许导航数据不多吧,但如果用作yahoo的关系词查询,这种设计就不行了。

写这样文章要化较大精力,最近忙很少有空了。以前写过文章,但思路有些不同,但自认数据库设计是最简洁的,通过程序可以实现所有功能。
www.5d.cn/bbs/newsdetail.asp?id=1260928&posts=current
www.5d.cn/bbs/newsdetail.asp?id=1324889&posts=current

可能深了,但这种讨论不可能不深。


非常大鱼

缺缺

职务:管理员
等级:8
金币:41.0
发贴:9620
#72005/5/9 20:18:09
有一个比较简单的js版本:


<script language="javascript">
function Class(){
	this.ID			=	new Array();
	this.Name		=	new Array();
	this.Count		=	new Array();
	this.Parent		=	new Array();
}
var MyClass = new Class();

<%

set rs=server.CreateObject("Adodb.Recordset")
sql="SELECT * FROM GameClass"
rs.open sql,conn,1,1
i=0
while not rs.eof
Response.Write("MyClass.ID["&i&"]		=	"""& rs("GameClass_ID") &""";"&vbcrlf)
Response.Write("MyClass.Name["&i&"]		=	"""& rs("GameClass_Name") &""";"&vbcrlf)
Response.Write("MyClass.Count["&i&"]	=	"""& rs("GameClass_Count") &""";"&vbcrlf)
Response.Write("MyClass.Parent["&i&"]	=	"""& rs("GameClass_ParentID") &""";"&vbcrlf)
Response.Write(vbcrlf)
i=i+1
rs.movenext
wend
rs.close()
set rs=nothing
%>

function GetClass(parentid){
var str="<table width=\"600\"  border=\"0\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\">";
if(MyClass.ID.length==0){
	str+="<tr><td>没有分类</td></tr>";
}else{
	for(var i=0;i<MyClass.ID.length;i++){
		if(parseInt(MyClass.Parent[i])==parentid){
			ot = new Option;
			ot.value=MyClass.ID[i];
			ot.text = MyClass.Name[i];
			document.all("ClassList").options.add(ot);
			str+="  <tr>";
			str+="<td width=\"2%\"><img src=\"../bbs/adminmanage/images/midnodeline.gif\" width=\"16\" height=\"22\"></td>";
			str+="   <td width=\"98%\"><strong>"+MyClass.Name[i]+"</strong>&nbsp;&nbsp;&nbsp;&nbsp;";
			str+="[<a href=\"javascript:;\" onclick=\"AddChild("+i+")\">添加子分类</a>]";
			str+=" [<a href=\"javascript:;\" onclick=\"EditItem("+i+")\">编辑</a>]";
			str+=" [<a href=\"?delid="+MyClass.ID[i]+"\" onclick=\"return confirm('确定删除 "+MyClass.Name[i]+" 么?\\n\\n如果删除分类会同时删除下级分类以及所有属于被删除分类的帖子')\">删除</a>]</td>";
			str+="  </tr><tr>";
			str+="    <td background=\"../bbs/adminmanage/images/vertline.gif\"></td>";
			str+="   <td>";
			str+=	GetClass(MyClass.ID[i]);
			str+="</td>  </tr>";
		}
	}
}
str+="</table>";
return str;
}
</script>