数据库中树形图的用法的用法你知道吗?下面我就跟你们详细介绍下数据库中树形图的用法的用法,希望对你们有用。
数据库中树形图的用法的用法如下:
树形图用于显示按照树形结构进行组织的数据,其用途比较广泛,如计算机中的文件系统(Windows中的资源管理器)、企业或公司的组成结构等。我们知道在Windows下VB、PB、Delphi等工具提供了一个功能很强的树型控件TreeView,利用Treeview控件可以方便地开发树形图。然而在网页上实现树形图就不那么容易了,现在在aspnet中利用微软提供的Internet Explorer WebControls它使得网页上的树形图开发与在Windows下一样的方便,一样的功能强大,甚至更灵活。
本文介绍用Internet Explorer WebControls开发树形图的方法,由于树形图结构较复杂,使用起来常不知如何下手。笔者结合最近刚为公司用ASPNET编写的应用程序管理器这一具体实例,详细阐述在ASPNET下如何将Internet Explorer WebControls的使用与数据库联系起来,实现数据分任意多层显示,方便地进行增加、修改、删除、移动 *** 作。笔者希望通过对该实例的阐述,达到抛砖引玉的效果,与各位同仁相互交流,共同进步。
Internet Explorer WebControls不在VSNET的标准Server Control中,要到微软的站点上下载,下载地址是:
>
这样的数据显示建议你用treeview或menu做,那样比较方便,如果你需求是要用gridview做的话,给你个大概方法,我做过按列显示的,估计你这按行也差不多,也就是判断数据是否相同,然后相同的单元格隐藏,第一个单元格就colspan加1,注意逻辑判断
你看下这个代码能不能套用 不是完全复制哈
using System;
using SystemCollectionsGeneric;
using SystemLinq;
using SystemText;
using SystemComponentModel;
using KingdeeBOS;
using KingdeeBOSUtil;
using KingdeeBOSCore;
using KingdeeBOSCoreDynamicForm;
using KingdeeBOSCoreDynamicFormPlugIn;
using KingdeeBOSCoreDynamicFormPlugInArgs;
using KingdeeBOSCoreDynamicFormPlugInControlModel;
using KingdeeBOSCoreMetadata;
namespace JDSampleFormPlugInDynamicForm
{
/// <summary>
/// </summary>
/// <remarks>
/// 案例背景:
/// 界面上使用树控件,需显示大量的节点;
/// 如果一次性加载到客户端,显示渲染会非常慢;
/// 因此,需要分层、分批下载
///
/// 案例说明:
/// 新增一个动态表单,挂上本插件,并在界面有一个树控件 F_JD_TreeView;
/// 界面初始化时,仅加载第一层节点;
/// 用户点击节点时,才加载其包含的子节点,而且每次最多加载10个;
/// 单层超过10个节点,通过"点击加载更多"节点,分批下载
/// </remarks>
[Description("分批分层加载树节点")]
public class S160107TreeEdit : AbstractDynamicFormPlugIn
{
/// <summary>
/// 本地变量,存储需加载到前端的所有节点信息,以及其是否已经加载标志
/// </summary>
private Dictionary<string, NodeInfo> _dctNodes = new Dictionary<string, NodeInfo>();
/// <summary>
/// 本地变量,存储已经被加载过的父节点Id,避免重复搜索其子节点,浪费时间
/// </summary>
private HashSet<string> _loadedNodeIds = new HashSet<string>();
/// <summary>
/// 界面初始化结束,触发此事件,通知插件开始加载树节点:在此事件,加载第一层节点
/// </summary>
/// <param name="e"></param>
public override List<TreeNode> GetTreeViewData(TreeNodeArgs e)
{
if (eKeyEqualsIgnoreCase("F_JD_TreeView") == false)
{
// 需加载是其他树控件的节点,略过
return new List<TreeNode>();
}
// 加载全部节点信息到内存
thisLoadNodes();
// 记录已经加载过根节点
this_loadedNodeIdsAdd("0");
// 展开树控件节点
TreeView tv = thisViewGetControl<TreeView>("F_JD_TreeView");
tvSetExpanded(true);
// 构造根目录下的第一层节点并返回
List<TreeNode> nodes = thisBuildTreeNodes("0");
return nodes;
}
/// <summary>
/// 用户点击节点时触发此事件:加载更多子节点
/// </summary>
/// <param name="e"></param>
public override void TreeNodeClick(TreeNodeArgs e)
{
if (eKeyEqualsIgnoreCase("F_JD_TreeView") == false)
{
// 点击的是其他树控件,略过
return;
}
// 判断是否已经加载过此节点的子节点,如果加载过,则不再加载
if (this_loadedNodeIdsContains(eNodeId))
{
return;
}
this_loadedNodeIdsAdd(eNodeId);
TreeView tv = thisViewGetControl<TreeView>("F_JD_TreeView");
string parentId = eNodeId;
if (parentIdStartsWith("more"))
{// 当前点击的节点,是"点击加载更多"
string[] keys = parentIdSplit('|');
parentId = keys[1]; // 第2部分为父节点部分
// "点击加载更多"节点已经被点击过,不再需要了,移除之
tvRemoveNode(eNodeId);
}
// 开始加载更多的子节点
List<TreeNode> childNodes = thisBuildTreeNodes(parentId);
if (childNodesCount > 0)
{
tvAddNodes(parentId, childNodes);
}
}
/// <summary>
/// 构建树控件所需要的节点对象
/// </summary>
/// <param name="parentId">父节点Id,为0表示第一层节点</param>
/// <returns></returns>
private List<TreeNode> BuildTreeNodes(string parentId)
{
List<TreeNode> nodes = new List<TreeNode>();
// 遍历全部节点,找指定节点中,未加载的子节点的子节点
int count = 0;
int index = 0;
foreach (var item in _dctNodes)
{
NodeInfo nodeInfo = itemValue;
if (nodeInfoLoaded == false
&& nodeInfoParentId == parentId)
{
nodeInfoLoaded = true;
count++;
TreeNode node = new TreeNode()
{
id = nodeInfoId,
text = nodeInfoCaption,
parentid = nodeInfoParentId,
};
nodesAdd(node);
}
if (count >= 10)
{// 本次加载超过了10个
// 生成一个特殊的节点(加载更多),并停止本批加载更多子节点
TreeNode node = new TreeNode()
{
// 需要基于如下需求,生成一个特殊的节点Id
// 1 需要与其他普通节点进行区分:以more为前缀
// 2 需要能够提取出父节点Id:包含父节点Id
// 3 每次产生的特殊节点Id不能重复:需包含当前节点索引
id = stringFormat("more|{0}|{1}", parentId, index),
text = "点击加载更多",
parentid = parentId,
};
nodesAdd(node);
break;
}
index++;
}
return nodes;
}
/// <summary>
/// 到数据库加载全部节点信息:本示例直接手工构建一批有层次的节点信息
/// </summary>
private void LoadNodes()
{
// 节点名称,包含其子节点的数量,以提示用户,可以展开查看子节点
// 第一层节点
_dctNodesAdd("1", new NodeInfo() { Id = "1", ParentId = "0", Caption = "江西(100)" });
_dctNodesAdd("2", new NodeInfo() { Id = "2", ParentId = "0", Caption = "广东(3)" });
// 循环添加100个第一层节点
for (int i = 3; i <= 100; i++)
{
_dctNodesAdd(iToString(), new NodeInfo()
{ Id = iToString(), ParentId = "0", Caption = stringFormat("省份{0}(0)", i) });
}
// 第二层节点:
_dctNodesAdd("11", new NodeInfo() { Id = "11", ParentId = "1", Caption = "南昌(0)" });
_dctNodesAdd("12", new NodeInfo() { Id = "12", ParentId = "1", Caption = "九江(0)" });
_dctNodesAdd("13", new NodeInfo() { Id = "13", ParentId = "1", Caption = "赣州(0)" });
// 循环添加100个第二层节点
for (int i = 4; i <= 100; i++)
{
_dctNodesAdd(stringFormat("1{0}", i),
new NodeInfo()
{
Id = stringFormat("1{0}", i),
ParentId = "1",
Caption = stringFormat("城市{0}(0)", i)
});
}
_dctNodesAdd("0201", new NodeInfo() { Id = "0201", ParentId = "02", Caption = "广州(0)" });
_dctNodesAdd("0202", new NodeInfo() { Id = "0202", ParentId = "02", Caption = "深圳(2)" });
_dctNodesAdd("0203", new NodeInfo() { Id = "0203", ParentId = "02", Caption = "惠州(0)" });
// 第三层节点:
_dctNodesAdd("020201", new NodeInfo() { Id = "020201", ParentId = "0202", Caption = "南山区" });
_dctNodesAdd("020202", new NodeInfo() { Id = "020202", ParentId = "0202", Caption = "宝安区" });
}
}
/// <summary>
/// 节点信息对象
/// </summary>
class NodeInfo
{
/// <summary>
/// 本节点Id
/// </summary>
public string Id { get; set; }
/// <summary>
/// 父节点Id
/// </summary>
public string ParentId { get; set; }
/// <summary>
/// 本节点标题
/// </summary>
public string Caption { get; set; }
/// <summary>
/// 是否已经加载标志:默认为false,未加载到前端
/// </summary>
public bool Loaded { get; set; }
}
}
树形结构一般都是用递归来实现展现的。你应该给出数据库里的几条记录,这样就知道你的树形数据是怎么组织的了,这么问别人很难给出你代码。不过你可以自己研究一下,很有助于提交的,在百度上搜“树形结构 递归”有很多结果。记住一点:树形正常都是递归实现。除非你的树有很特殊的需求。
先从数据结构的角度来答
题主应该知道B-树和B树最重要的一个区别就是B树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域
这就决定了B树更适合用来存储外部数据,也就是所谓的磁盘数据
从Mysql(Inoodb)的角度来看,B树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上
那么Mysql如何衡量查询效率呢?磁盘IO次数,B-树(B类树)的特定就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,当查询数据的时候,最好的情况就是很快找到目标索引,然后读取数据,使用B树就能很好的完成这个目的,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时啊!),而B树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少
这是优点之一
另一个优点是什么,B树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来
这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦
至于MongoDB为什么使用B-树而不是B树,可以从它的设计角度来考虑,它并不是传统的关系性数据库,而是以Json格式作为存储的nosql,目的就是高性能,高可用,易扩展
首先它摆脱了关系模型,上面所述的优点2需求就没那么强烈了,其次Mysql由于使用B树,数据都在叶节点上,每次查询都需要访问到叶节点,而MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)
总体来说,Mysql选用B树和MongoDB选用B-树还是以自己的需求来选择的
以上就是关于数据库中树形图的用法全部的内容,包括:数据库中树形图的用法、asp.netmvc5如何实现打开树形结构链接后保持树形结构、ASP.NET中的gridview中怎么让显示的数据成树形结构,数据从数据库中读等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)