扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
树状结构的数据保存在数据库中的常用方法有一下两种:
创新互联公司基于分布式IDC数据中心构建的平台为众多户提供四川雅安服务器托管 四川大带宽租用 成都机柜租用 成都服务器租用。
1、邻接表(adjacency list model)
2、预排序遍历树算法(modified preorder tree traversal algorithm)
用一下的例子讨论这两种方法的差异:
现有一棵树如下:
邻接表模式:
这种模式我们经常用到,很多的教程和书中也介绍过。我们通过给每个节点增加一个属性 parent 来表示这个节点的父节点从而将整个树状结构通过平面的表描述出来。根据这个原则,例子中的数据可以转化成如下的表:
我们看到 Pear 是Green的一个子节点,Green是Fruit的一个子节点。而根节点'Food'没有父节点。 为了简单地描述这个问题, 这个例子中只用了name来表示一个记录。 在实际的数据库中,你需要用数字的id来标示每个节点,数据库的表结构大概应该像这样:id, parent_id, name, description。
以下是代码:
?php
// $parent is the parent of the children we want to see
// $level is increased when we go deeper into the tree,
// used to display a nice indented tree
function display_children($parent, $level)
{
// 获得一个 父节点 $parent 的所有子节点
$result = mysql_query('SELECT name FROM tree '.
'WHERE parent="'.$parent.'";');
// 显示每个子节点
while ($row = mysql_fetch_array($result))
{
// 缩进显示节点名称
echo str_repeat(' ',$level).$row['name']."n";
//再次调用这个函数显示子节点的子节点
display_children($row['name'], $level+1);
}
}
?
对整个结构的根节点(Food)使用这个函数就可以打印出整个多级树结构,由于Food是根节点它的父节点是空的,所以这样调用: display_children('',0)。将显示整个树的内容:
Food
Fruit
Red
Cherry
Yellow
Banana
Meat
Beef
在 MySQL 表中存储树形结构数据:
一般比较普遍的就是四种方法:(具体见 SQL Anti-patterns这本书)
Adjacency List:每一条记录存parent_id
Path Enumerations:每一条记录存整个tree path经过的node枚举
Nested Sets:每一条记录存 nleft 和 nright
Closure Table:维护一个表,所有的tree path作为记录进行保存。
表结构
这种情况可以通过左连接实现
可以看到左连接是以左表为基准,通过关联关系id = pid去找到对应的上级组织记录,所以空的id找不到对应的记录,返回空
有时候我们需要获取某个组织的完整路径 如
部门C/部门C_2/部门C_2_1/部门C_2_1_1
编写存储过程,生成一个临时表tmpLst,按照层级把每一条记录插入到临时表,然后每次从临时表查当前层级的组织,循环去查组织表的上级组织,直到结果ROW_COUNT = 0为止,代表当前层级下的所有组织已经是最后一级
查询到的结果,大家可以自行优化一下显示方式和查询的字段
当然还有另一种方式,从设计上解决
如新加一个唯一约束,把组织的约束定义为 ORG_001_ORG_001_002_ORG_001_003 这样的形式
当需要查询ORG_001所有的下级时,只需要查询约束 like ORG_001% 即可
当需要查询ORG_001_002所有上级时,只需要查询约束 like %ORG_001_002
不过问题在于如果组织的存在架构调整,如,ORG_001_002调整到了 ORG_002下,因为树型结构变化了,直接用like无法查询到正确数据,这个时候要考虑是否允许调整或者调整后修改对应的唯一约束
方法/步骤
首先我们需要在mysql管理工具上面新建一个表,也可以用mysql命令创建,表建立完成之后,你需要将表中的字段名字告诉给填写excel表的人员.
请点击输入图片描述
打开excel表,按照程序提供的字段填写相应的数据.此时注意下面几点:名字(我用红色标示出来了)需要跟程序提供的一样,其他的描述,表头可以不写都行.
请点击输入图片描述
我使用的mysql管理工具是Navicat for MySQL,打开工具,选择表所在的数据库,然后点击数据库名字,右键数据,出来下拉菜单选择import wizard ,有汉化版本的更明确.弹出一个选择界面,我们选择excel file文件
请点击输入图片描述
请点击输入图片描述
点击next(下一步),我们选择我们对应的excel文件就行,然后再下面选在我们的文件内容在哪一个sheet中,也就是你的内容写在excel什么地方,这点需要注意,也是关键的地方,我的内容在sheet3中,所以我选择sheet3 ,如图:
请点击输入图片描述
点击next (此步骤也是关键步骤),需要注意2点: 1:filed name row 就是你的字段所在excel中的位置,也就是第几行(简单办法,一般就是英文对应的那一列).2:first data row(从哪一行开始执行),数据从哪一行开始呢,我这里选择的是3,4.
请点击输入图片描述
点击next 我们选择 target table 目标对应的数据库,选择你要导入到哪个数据库中表中.
请点击输入图片描述
如果到上面一步没有问题的话,我们默认next到最后 就行了.然后打开表就能看到数据跟excel表中的一样.
请点击输入图片描述
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流