数据库中树形图的用法

数据库中树形图的用法,第1张

数据库中树形图的用法的用法你知道吗?下面我就跟你们详细介绍下数据库中树形图的用法的用法,希望对你们有用。

数据库中树形图的用法的用法如下:

树形图用于显示按照树形结构进行组织的数据,其用途比较广泛,如计算机中的文件系统(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中怎么让显示的数据成树形结构,数据从数据库中读等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10195122.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存