精华内容
下载资源
问答
  • 众所周知mysql没有oracle 的递归查询,如果Java代码中查询的话。列表页几十条数据。在每个节点层数不定时,其实时间都花费在数据库的连接上。 又不想mysql增加自定义函数(个人觉得不利于数据迁移)。所以学习了...

    公司要做一个树状结构,列表展示的时候不仅要有节点信息,还要有该节点的路径信息。

    众所周知mysql没有oracle 的递归查询,如果Java代码中查询的话。列表页几十条数据。在每个节点层数不定时,其实时间都花费在数据库的连接上。

    又不想mysql增加自定义函数(个人觉得不利于数据迁移)。所以学习了一下前人的树状结构表设计。

    首先解决拿来主义

    将第一套理论和第二套理论整合到一起。既可以解决效率问题,也可以满足常用的需求,当树状结构进行管理时。关联树状结构的信息只需要保存节点id就可以了。

    树状结构变更时,tree_path的parent_id 都需要维护。

    CREATE TABLE `event_link_tree` (
      `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '节点ID',
      `name` varchar(255) NOT NULL DEFAULT '' COMMENT '节点名称',
      `paernt_id` bigint(11) NOT NULL DEFAULT '0' COMMENT '父节点ID',
      `tree_path` varchar(255) NOT NULL DEFAULT '' COMMENT '节点路径信息例如/1/2/3/',
      `creater` varchar(255) NOT NULL DEFAULT '' COMMENT '创建者',
      `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_by` varchar(255) NOT NULL DEFAULT '' COMMENT '修改者',
      `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
      `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

    方案一(Adjacency List)

    CREATE TABLE tree(
    node_id int,
    
    node_name varchar2(100),
    
    parent_id int
    
    );

    这种结构应该是目前最常用的。

    优点:1 便于直接查询已知节点的上下级节点。

               2 增删改查比较便捷

    缺点:无法一次查询得到层级关系。

    方案二(Path Enumeration)

    CREATE TABLE tree_Path(
    node_id int,
    
    node_name varchar2(100),
    
    path varchar2(1000)
    
    );

    例子

    优点:

    1 解决了第一种方案的缺点无法查询路径的问题

    2 而且可以通过以下的方法查询节点的父节点和子节点。

    select id ,name,tree_path from event_link_tree where tree_path like '/1/2/%'
    select id ,name,tree_path from event_link_tree where tree_path like '%/2/%'

     

     

    另外两种,因为不符合自己的场景,所以不做细致说明,参考大牛文章,链接如下

    https://blog.csdn.net/biplusplus/article/details/7433625

    展开全文
  • 2、直接自定义MySQL函数getParentNodeList,通过一层while循环,实现对指定节点的所有父子节点进行查询。功能实现1、创建数据表1)表结构截图如下(此处简单建一张表t_tree,id主键自增,uuid表示本节点,pa...

    背景说明

    需求:MySQL树形结构, 根据指定的节点,获取其所有父节点序列。

    问题分析

    1、可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取父节点。

    2、直接自定义MySQL函数 getParentNodeList,通过一层while循环,实现对指定节点的所有父子节点进行查询。

    功能实现

    1、创建数据表

    1)表结构截图如下(此处简单建一张表t_tree,id主键自增,uuid表示本节点,parent_uuid表示父节点):

    2)建表语句如下:

    /*

    Navicat Premium Data Transfer

    Source Server : localhost

    Source Server Type : MySQL

    Source Server Version : 50724

    Source Host : localhost:3306

    Source Schema : test_db

    Target Server Type : MySQL

    Target Server Version : 50724

    File Encoding : 65001

    Date: 07/05/2019 21:04:57

    */

    SET NAMES utf8mb4;

    SET FOREIGN_KEY_CHECKS = 0;

    -- ----------------------------

    -- Table structure for t_tree

    -- ----------------------------

    DROP TABLE IF EXISTS `t_tree`;

    CREATE TABLE `t_tree` (

    `id` int(20) NOT NULL AUTO_INCREMENT,

    `uuid` int(20) NULL DEFAULT NULL,

    `parent_uuid` int(20) NULL DEFAULT NULL,

    PRIMARY KEY (`id`) USING BTREE

    ) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

    -- ----------------------------

    -- Records of t_tree

    -- ----------------------------

    INSERT INTO `t_tree` VALUES (1, 1, 0);

    INSERT INTO `t_tree` VALUES (2, 2, 0);

    INSERT INTO `t_tree` VALUES (3, 3, 0);

    INSERT INTO `t_tree` VALUES (4, 11, 1);

    INSERT INTO `t_tree` VALUES (5, 12, 1);

    INSERT INTO `t_tree` VALUES (6, 21, 2);

    INSERT INTO `t_tree` VALUES (7, 22, 2);

    INSERT INTO `t_tree` VALUES (8, 211, 21);

    INSERT INTO `t_tree` VALUES (9, 221, 22);

    INSERT INTO `t_tree` VALUES (10, 222, 22);

    INSERT INTO `t_tree` VALUES (11, 223, 22);

    INSERT INTO `t_tree` VALUES (12, 2231, 223);

    INSERT INTO `t_tree` VALUES (13, 2232, 223);

    INSERT INTO `t_tree` VALUES (14, 0, );

    SET FOREIGN_KEY_CHECKS = 1;

    3)表数据结构如下:

    4)树形结构如下图:

    2、编写查询叶子节点函数 getParentNodeList,如下:

    CREATE DEFINER=`root`@`localhost` FUNCTION `getParentNodeList`(`nodeId` int) RETURNS varchar(1000) CHARSET utf8

    BEGIN

    DECLARE parentList VARCHAR(1000); # 返回父节点结果集

    DECLARE tempParent VARCHAR(1000); # 临时存放父节点

    SET parentList = '';

    SET tempParent = CAST(nodeId as CHAR); # 将int类型转换为String

    WHILE tempParent is not null DO # 循环,用于查询节点上所有的父节点

    SET parentList = CONCAT(parentList, ',', tempParent); # 存入到返回结果中

    SELECT parent_uuid INTO tempParent FROM t_tree where uuid = tempParent; # 查询节点上所有父节点

    END WHILE;

    RETURN SUBSTRING(parentList, 2); # 将返回结果处理,截取掉结果集前面的逗号

    END

    其中,用到了很多MySQL的系统函数,如:CAST,SUBSTRING,CONCAT。

    3、调用函数

    select getParentNodeList(2232) as parentNodeList;

    0)查询节点0 的父节点:从树形图可以看到,应该是 0

    1)查询节点21 的父节点:从树形图可以看到,应该是 21,2,0

    2)查询节点211 的父节点:从树形图可以看到,应该是 211,21,2,0

    3)查询节点2231 的父节点:从树形图可以看到,应该是 2231,223,22,2,0

    问题总结

    该问题核心点是循环查找父节点,按照上面的表数据和截图,阅读SQL函数,很好理解。

    希望能帮到需要帮助的同行,谢谢。

    PS:

    如果需要 根据指定的节点,获取其下属的所有子节点(包含路径上的所有枝干节点和叶子节点)。

    标签:INSERT,SET,INTO,tree,树形,VALUES,MySQL,节点

    来源: https://www.cnblogs.com/miracle-luna/p/10878224.html

    展开全文
  • 结构和表数据就不公示了,查询的表user_role,主键是id,每条记录有parentid字段; 如下mysql查询函数即可实现根据一个节点查询所有的子节点,根据一个子节点查询所有的父节点。对于数据量较大的时候(我这里测试...

    表结构和表数据就不公示了,查询的表user_role,主键是id,每条记录有parentid字段;

    如下mysql查询函数即可实现根据一个节点查询所有的子节点,根据一个子节点查询所有的父节点。对于数据量较大的时候(我这里测试的1万条左右)。查询效率非常慢。建议在java代码中进行处理。

    CREATE FUNCTION `getChildList`(rootId INT)
        RETURNS varchar(1000)
        BEGIN
          DECLARE sChildList VARCHAR(1000);
          DECLARE sChildTemp VARCHAR(1000);
          SET sChildTemp =cast(rootId as CHAR);
          WHILE sChildTemp is not null DO
            IF (sChildList is not null) THEN
              SET sChildList = concat(sChildList,',',sChildTemp);
        ELSE
          SET sChildList = concat(sChildTemp);
        END IF;
            SELECT group_concat(id) INTO sChildTemp FROM user_role where FIND_IN_SET(parentid,sChildTemp)>0;
          END WHILE;
          RETURN sChildList;
        END;
    /*获取子节点*/
    /*调用: 1、select getChildList(0) id; 
    2、select * 5From user_role where FIND_IN_SET(id, getChildList(2));
    */
     
     
    CREATE FUNCTION `getParentList`(rootId INT)
        RETURNS varchar(1000)
        BEGIN
          DECLARE sParentList varchar(1000);
          DECLARE sParentTemp varchar(1000);
          SET sParentTemp =cast(rootId as CHAR);
          WHILE sParentTemp is not null DO
        IF (sParentList is not null) THEN
             SET sParentList = concat(sParentTemp,',',sParentList);
        ELSE
         SET sParentList = concat(sParentTemp);
        END IF;
            SELECT group_concat(parentid) INTO sParentTemp FROM user_role where FIND_IN_SET(id,sParentTemp)>0;
          END WHILE;
          RETURN sParentList;
        END;
    /*获取父节点*/
    /*调用: 1、select getParentList(6) id; 
    2、select * From user_role where FIND_IN_SET(id, getParentList(2));
    
    */

     

    展开全文
  • 通过以下sql可以取出指定organization_id所在的树状结构枝干上所有的organization_id: <select id="queryBranchIds" parameterType="java.lang.String" resultType="java.lang.String"> ( -- 查找所有子孙o

    mysql数据库表person_organization中,主键是organization_id,另有一列parent_organization_id指向父机构的数据记录;通过以下sql可以取出指定organization_id所在的树状结构枝干上所有的organization_id:

    <select id="queryBranchIds" parameterType="java.lang.String" resultType="java.lang.String">
    (
    -- 查找所有子孙organization_id
    SELECT organization_id FROM (
    SELECT t1.organization_id,
    if (FIND_IN_SET(parent_organization_id, @pids) > 0, @pids := CONCAT(@pids, ',', organization_id), 0) AS ischild
    FROM 
    (SELECT organization_id, parent_organization_id FROM person_organization t WHERE t.status = '0' ORDER BY parent_organization_id, organization_id, type) t1,
    (SELECT @pids := #{organizationId}) t2
    ) t3 WHERE ischild != '0'
    )
    UINION
    (
    -- 查找所有父祖organization_id
    SELECT t2.organization_id from (
    SELECT @r as _id,
    (SELECT @r := parent_organization_id FROM person_organization
    WHERE organization_id = _id) as parent_organization_id, @l := @l + 1 as lvl FROM
    (SELECT @r := #{organizationId}, @l := '') vars, person_organization h WHERE @r <![CDATA[ <> ]]> '' and h.status = '0') t1 join person_organization t2 on t1._id = t2.organization_id order by t1.lvl asc 
    )
    </select>

     

    展开全文
  • 初识Mysql ...层次模型,为树状结构,是Java 中的继承模式。 网状模型,有多个父节点,多继承模式。 关系模型,关系模型,是存放一个实体,和属性 SQL的概念 结构化查询语言(Structured Query Lang...
  • 一:J2SE面向对象-封装、继承、多态内存的分析递归集合类、泛型、... 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器数据库设计三范式、3:JDBCJDBC基础连接池树状结构存储与展现DataSour...
  • java学习流程

    2015-01-08 08:44:00
    J2SE面向对象-封装、继承、多态内存的分析递归集合类、泛型、自动打包与解包、... 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器数据库设计三范式、3:JDBCJDBC基础连接池树状结构存...
  • java 学习目录大纲

    千次阅读 2017-01-12 14:00:22
    java学习目录 后端技术 1.ssh+ssm+webService(http/client)+数据结构+简单算法(递归、二分)+设计模式(工厂、单列、代理)  1.1 think in java  1.2 servlet api  ... 2.1.2 树状查询(自连查询)
  • JAVA学习路线

    2012-08-01 14:26:00
    2:数据库(Oracle或者MySQL)SQL语句多表连接,内外连接, 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器 数据库设计三范式、 3:JDBCJDBC基础连接池 树状结构存储与...
  • 01 J2SE 面向对象-封装、继承、多态02 内存的分析03 递归04 集合类、泛型、自动打包与解包、Annotation05 IO06 多线程、线程同步...内外连接, 子查询等14 管理表、视图、索引、序列、约束等15 树状结构存储16 存储...
  • java知识点

    2019-10-02 00:45:55
    一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation IO 多线程、线程同步 ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子...树状结构存储 存储过程、...
  • JAVA自学之路

    2019-05-02 13:03:03
    路线图明细 下面给出第二节《JAVA自学路线图》中知识点的明细: 一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation IO 多线程、线程同步 ...树状结构存储 ...
  • Java 学习路线

    2010-03-19 16:27:00
    学习路线一:J2SE 面向对象-封装、继承、多态内存的分析递归集合类、...内外连接, 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器 数据库设计三范式、3:JDBCJDBC基础连接池 树状结构存储与
  • java自学路线

    2009-09-15 23:43:00
    一:J2SE 面向对象-封装、继承、多态内存的分析递归集合类、...内外连接, 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器 数据库设计三范式、3:JDBCJDBC基础连接池 树状结构存储与展现Da
  • Java学习路线

    2017-09-15 21:41:00
    ...1:J2SE 面向对象-封装、继承、多态内存的分析递归集合类、泛型、自动打包与解包、AnnotationIO多线程、线程同步TCP/... 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器数...
  • java 学习流程图

    2014-03-17 17:36:00
    java学习流程 ...J2SE面向对象-封装、继承、多态内存的分析递归集合类、泛型、自动打包与解包、AnnotationIO多线程、... 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器数据库设...
  • java学习路线

    2014-12-07 23:15:46
    一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储 存储过程、触发
  • Java之路

    2013-06-05 19:00:15
    一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation IO 多线程、线程同步 ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储
  • JAVA学习方向

    2012-05-24 09:35:44
    一:J2SE  面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation  ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储 存储过程、触发器
  • java学习方法

    2011-12-01 22:48:53
    一:J2SE  面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation  ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储 存储过程、触发器
  • JAVA自学路线图》

    2010-07-23 11:02:00
    <br />《JAVA自学路线图》中知识点的明细:...内外连接, 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器 数据库设计三范式、 3:JDBCJDBC基础连接池 树状结构存储与展现DataSourc
  • Java学习路线图

    千次阅读 2009-05-10 11:20:00
    Java学习路线图 作者:马士兵 1:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型...SQL语句 多表连接,内外连接, 子查询等 管理表、视图、索引、序列、约束等 树状结构存储 存储过程、触发器 数据库
  • java学习路线图明细

    2009-11-27 22:28:00
    一:J2SE 面向对象-封装、继承、多态内存的分析递归集合类、泛型、自动打包...内外连接, 子查询等管理表、视图、索引、序列、约束等树状结构存储存储过程、触发器 数据库设计三范式、3:JDBCJDBC基础连接池 树状结构
  • Java学习过程

    2009-05-25 10:57:22
    一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储 ...
  • JAVA学习过程

    2009-05-24 23:12:37
    一:J2SE 面向对象-封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation ...2:数据库(Oracle或者MySQL) ...多表连接,内外连接, 子查询等 ...树状结构存储 ...

空空如也

空空如也

1 2 3
收藏数 59
精华内容 23
关键字:

java树状结构查询mysql

java 订阅
mysql 订阅