今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢?

  像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的人,就很难驾驭了。

  举个栗子:现在有一个要存储一下公司的人员结构,大致层次结构如下:

  (画个图真不容易。。)

  那么怎么存储这个结构?并且要获取以下信息:

  1.查询小天的直接上司。

  2.查询老宋管理下的直属员工。

  3.查询小天的所有上司。

  4.查询老王管理的所有员工。

  

方案一、(Adjacency List)只存储当前节点的父节点信息。

  CREATE TABLE Employees(
  eid int,
  ename VARCHAR(100),
        position VARCHAR(100),
  parent_id int
  )

  记录信息简单粗暴,那么现在存储一下这个结构信息:

  

  好的,现在开始进入回答环节:

  1.查询小天的直接上司:

  SELECT e2.eid,e2.ename FROM employees e1,employees e2 WHERE e1.parent_id=e2.eid AND e1.ename='小天';

  

  2.查询老宋管理下的直属员工:

  SELECT e1.eid,e1.ename FROM employees e1,employees e2 WHERE e1.parent_id=e2.eid AND e2.ename='老宋';

  

  3.查询小天的所有上司。

  这里肯定没法直接查,只能用循环进行循环查询,先查直接上司,再查直接上司的直接上司,依次循环,这样麻烦的事情,还是得先建立一个存储过程:

  睁大眼睛看仔细了,接下来是骚操作环节:

CREATE DEFINER=`root`@`localhost` FUNCTION `getSuperiors`(`uid` int) RETURNS varchar(1000) CHARSET gb2312
BEGIN
DECLARE superiors VARCHAR(1000) DEFAULT '';
DECLARE sTemp INTEGER DEFAULT uid;
DECLARE tmpName VARCHAR(20); WHILE (sTemp>0) DO
SELECT parent_id into sTemp FROM employees where eid = sTemp;
SELECT ename into tmpName FROM employees where eid = sTemp;
IF(sTemp>0)THEN
SET superiors = concat(tmpName,',',superiors);
END IF;
END WHILE;
SET superiors = LEFT(superiors,CHARACTER_LENGTH(superiors)-1);
RETURN superiors;
END

  这一段存储过程可以查询子节点的所有父节点,来试验一下 

  好的,骚操作完成。

  显然,这样。获取子节点的全部父节点的时候很麻烦。。

  4.查询老王管理的所有员工。

  思路如下:先获取所有父节点为老王id的员工id,然后将员工姓名加入结果列表里,在调用一个神奇的查找函数,即可进行神奇的查找:

CREATE DEFINER=`root`@`localhost` FUNCTION `getSubordinate`(`uid` int) RETURNS varchar(2000) CHARSET gb2312
BEGIN   
DECLARE str varchar(1000);  
DECLARE cid varchar(100);
DECLARE result VARCHAR(1000);
DECLARE tmpName VARCHAR(100);
SET str = '$';   
SET cid = CAST(uid as char(10));   
WHILE cid is not null DO   
  SET str = concat(str, ',', cid);
  SELECT group_concat(eid) INTO cid FROM employees where FIND_IN_SET(parent_id,cid);         
END WHILE;
  SELECT GROUP_CONCAT(ename) INTO result FROM employees WHERE FIND_IN_SET(parent_id,str);
RETURN result;   
END

  看神奇的结果:

 

  虽然搞出来了,但说实话,真是不容易。。。

  这种方法的优点是存储的信息少,查直接上司和直接下属的时候很方便,缺点是多级查询的时候很费劲。所以当只需要用到直接上下级关系的时候,用这种方法还是不错的,可以节省很多空间。后续还会介绍其它存储方案,并没有绝对的优劣之分,适用场合不同而已。

  本篇至此告一段落,欢迎大家继续关注。

【MySQL疑难杂症】如何将树形结构存储在数据库中(方案一、Adjacency List)的更多相关文章

  1. Java实现购物车功能:方式一:存放在session中.方式二:存储在数据库中

    //将购物车产品加入到cookie中,方式同浏览记录.Java实现购物车,方式一(简易版):存储在session中.这种方式实现还不严谨,大家看的时候看思路即可.(1). JSP页面中,选择某一款产品 ...

  2. js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中

    ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId ...

  3. 数据库:MySQL实战;左链接;查询WordPress数据库中的文章内容

    在1年前,我用学生价租了一个阿里云服务器(是真的便宜啊),自己在CentOS系统上用命令行搭了个WordPress的环境,开始了为期一个月使用自建博客的历程. 事实证明,博客在类似博客园这样的平台上写 ...

  4. ASP.NET中让图片以二进制的形式存储在数据库中

    今早有个网友问到我这问题,以前我都是直接在数据库中存文件名的,还没有试过存储整张图片到数据库中,上网搜索了一下,自己又测试了一番,代码如下:建立保存图片的表的SQL语句: USE [niunantes ...

  5. spring cloud config将配置存储在数据库中

    Spring Cloud Config Server最常见是将配置文件放在本地或者远程Git仓库,放在本地是将将所有的配置文件统一写在Config Server工程目录下,如果需要修改配置,需要重启c ...

  6. 将文件存储到数据库中(MySQL)

    package com.play; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...

  7. mysql的load data,高速将文本文件,插入数据库中

    1语法 LOAD DATA [ LOW_PRIORITY | CONCURRENT ] [ LOCAL ] INFILE 'file_name.txt' [ REPLACE | IGNORE ] IN ...

  8. 存储过程: 存储过程(stored procedure)有时也称为sproc。存储过程存储于数据库中而不是在单独的文件中,有输入参数、输出参数以及返回值等。

    存储过程示例一: 执行存储过程方法一: 执行存储过程方法二: 存储过程可以定义返回值: 修改存储过程: 利用存储过程查找三个表内的信息: 练习:  超市管理系统:表一:门店仓库表   MenDian ...

  9. Android端上传图片到后台,存储到数据库中 详细代码

    首先点击头像弹出popwindow,点击相册,相机,调用手机自带的裁剪功能,然后异步任务类访问服务器,上传头像,保存到数据库中, 下面写出popwindow的代码 //设置popwindow publ ...

随机推荐

  1. css实现的交互运动

    <style type="text/css"> .filter-mix { position: absolute; top: 50%; left: 50%; trans ...

  2. hack查询地址

    悲催的IE! http://browserhacks.com/

  3. 学习笔记TF052:卷积网络,神经网络发展,AlexNet的TensorFlow实现

    卷积神经网络(convolutional neural network,CNN),权值共享(weight sharing)网络结构降低模型复杂度,减少权值数量,是语音分析.图像识别热点.无须人工特征提 ...

  4. Windows搭建golang开发平台

    Golang是谷歌开发的一款开源性语言,暂时比较方便的IDE有Inteillj Idea.LiteIDE.Eclipse(Golipse)等,使用起来比较方便的IDE:LiteIDE和Inteillj ...

  5. 个性化推荐系统(七)--- ABTest ab测试平台

    个性化推荐系统.搜索引擎.广告系统,这些系统都需要在线上不断上线,不断优化,优化之后怎么确定是好是坏.这时就需要ABTest来确定,最近想的办法.优化的算法.优化的逻辑数据是正向的,是有意义的,是提升 ...

  6. hadoop集群服务器配置注意事项

    1.使用root账户,一劳记逸,远离权限问题. 2.关闭防火墙,命令:service iptables stop 想永久关闭,命令为:chkconfig iptables off 查看防火墙状态,命令 ...

  7. 中高级JavaScript易错面试题

    写出下题的输出 1.函数的实参与形参length var length = 10; function fn() { console.log(this.length); } var obj = { le ...

  8. linux下使用crontab实现定时PHP计划任务失败的原因分析

    这篇文章主要介绍了linux下使用crontab实现定时PHP计划任务失败的原因分析,需要的朋友可以参考下   很多人在linux下使用crontab实现PHP执行定时任务却未能成功,不能生成缓存.本 ...

  9. 使用SimpleXML解析xml文件数据

    最近工作要求从一个XML文档中批量读取APK应用数据,自然想到用SimpleXML.经过一段时间摸索,终于成功解析,现在将思路以及代码做下记录: xml文件格式大致如下: <?xml versi ...

  10. Spring框架学习之高级依赖关系配置(二)

    紧接着上篇内容,本篇文章将主要介绍XML Schema的简化配置和使用SpEL表达式语言来优化我们的配置文件. 一.基于XML Schema的简化配置方式 从Spring2.0以来,Spring支持使 ...