1、树形结构应用场景

有时我们需要保存一些树形的数据,比如组织架构、话题讨论、知识管理、商品分类等,这些数据之间存在一种递归关系,很多开发人员想到的第一个解决方案往往是记录每个节点的父节点,例如以下的评论表。

CREATE TABLE comments (

comment_id int(10)  NOT NULL,

parent_id int(10)  DEFAULT NULL,

comment text  NOT NULL,

PRIMARY KEY (comment_id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

采用这样的结构,就需要编写复杂的代码递归检索很多记录,查询的效率就会很低。如果数据量不大、讨论内容相对固定,数据的层次较少,那么采用这样的结构就会是简单的、清晰的,这种情况下此结构还是合适的;但如果数据量很大,查询就会变得很复杂。下面介绍两种更通用,扩展性更好的解决方案:路径枚举和闭包表。

2、路径枚举(增加一个字段存储所有父级节点信息,用特殊符号分割开)

基于上面的表结构,可以增加一个字段path,用于记录节点的所有祖先信息。记录的方式是把所有的祖先信息组织成一个字符串。

因为路径(path)字段包含了该节点的所有祖先信息,所以可以轻易地获取某个节点的所有祖先节点,可以用程序先获取path字符串,然后再使用切割字符串的函数处理得到所有的祖先节点。

如果要查找某个节点的所有后代,例如查找comment_id等于3的所有后代,可以使用如下的查询语句。

SELECT * FROM comments WHERE path LIKE ‘1/3/_%’;

如果要查找下一层子节点,可以使用如下的查询语句

SELECT * FROM comments WHERE path REGEXP “^1/3/[0-9]+/$”;

插入操作也比较简单,只需要复制一份父节点的路径,并将新节点的ID值(comment_id)添加到路径末尾就可以了。

枚举路径的方式使得查询子树和祖先都变得更加简单,查看分隔符即可知道节点的层次,虽然冗余存储了一些数据,应用程序需要额外增加代码以确保路径信息的正确性,但这种设计的扩展性更好,更能适应未来数据的不断增长。表5-2中,仍然保留了parent_id列,是为了使一些操作更加方便,也可以用来校验路径信息是否正确。

3、闭包表(增加一张父子节点关联关系表)

闭包表也是一种通用的方案,它需要额外增加一张表,用于记录节点之间的关系。它不仅记录了节点之间的父子关系,也记录了树中所有节点之间的关系。

使用如下命令语句新建表path

CREATE TABLE path (

ancestor int(11) NOT NULL,

descendant int(11) NOT NULL,

PRIMARY KEY (ancestor,descendant)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

ancestor表示祖先,descendant表示后代,存储的是comment_id值。

如果要统计comment_id等于3的所有后代(不包括其自身),可以直接搜索path表祖先是3的记录即可得到,查询语句如下:

SELECT COUNT(*) FROM path WHERE ancestor=3 AND descendant <> 3;

为了更方便地查询直接父节点/子节点,可以增加一个path_length字段以表示深度,节点的自我引用path_length等于0,到它的直接子节点的path_length等于1,再下一层为2,以此类推。

如上所述的数据结构,新增了一个表,用于存储节点之间的信息,是一种典型的“以空间换时间”的方案,而且一个节点可以属于多棵树。相对于路径枚举,闭包表的节点关系更容易维护。

文章基于MySQL DBA修炼之道整理,版权属于原作者

mysql树形结构的效率_MySQL存储树形数据优化技笔记相关推荐

  1. MySQL存储树形数据优化技笔记

    1.树形结构应用场景 有时我们需要保存一些树形的数据,比如组织架构.话题讨论.知识管理.商品分类等,这些数据之间存在一种递归关系,很多开发人员想到的第一个解决方案往往是记录每个节点的父节点,例如以下的 ...

  2. MySQL—通过Adjacency List(邻接表)存储树形结构

    转载自:Mysql通过Adjacency List(邻接表)存储树形结构 今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢?像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数 ...

  3. mysql引擎层存储层_MySQL存储底层技术:InnoDB底层原理解读

    原标题:MySQL存储底层技术:InnoDB底层原理解读 存储引擎 很多文章都是直接开始介绍有哪些存储引擎,并没有去介绍存储引擎本身.那么究竟什么是存储引擎?不知道大家有没有想过,MySQL是如何存储 ...

  4. mysql innodb和myisam区别_MySQL?存储引擎简介

    ​大家好,我是anyux.本文介绍MySQL存储引擎. 简介 相当于Linux文件系统,只不过比文件系统强大 功能 数据读写 数据安全和一致性 提高性能 热备份 自动故障恢复 高可用方面支持 引擎类别 ...

  5. mysql建表影响效率_MySQL建表查询优化技巧

    场景 我用的数据库是mysql5.6,下面简单的介绍下场景 课程表: 数据100条 学生表: 数据70000条 学生成绩表SC 数据70w条 查询目的:查找语文考100分的考生 查询语句: selec ...

  6. mysql部门人员排序设计_MySQL数据库访问性能优化

    MYSQL应该是最流行的WEB后端数据库.大量应用于PHP,Ruby,Python,Java 等Web语言开发项目中,无论NOSQL发展多么快,都不影响大部分架构师选择MYSQL作为数据存储. MYS ...

  7. MySQL中一个B+树能存储多少数据

    MySQL聚簇索引的存储结构 MySQL中InnoDB页的大小默认是16k.也可以自己进行设置.(计算机在存储数据的时候,最小存储单元是扇区,一个扇区的大小是 512 字节,而文件系统(例如 XFS/ ...

  8. mysql gis index 索引原理_Mysql 索引原理及优化

    Mysql 索引原理及优化 什么是索引 为什么需要索引? 索引是数据表种一个或者多个列进行排序的数据结构 索引能够大幅提升检索速度 创建.更新索引本身也会耗费空间和时间 查找结构进化史 线性查找:一个 ...

  9. mysql导出数据库对象命令_mysql数据库导出数据(命令)

    MySQL数据库数据导出 一.导出命令 导出所有数据库: mysqldump -u [数据库用户名] -p -A>[备份文件的保存路径] 导出数据和数据结构: mysqldump -u [数据库 ...

最新文章

  1. 动态路由选择协议(三)链路状态路由选择协议
  2. 电脑卡顿不流畅怎么解决_使命召唤17画面卡顿怎么办-使命召唤17画面卡顿解决方法...
  3. MySQL数据迁移到SQL Server
  4. Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串...
  5. Codeforce 1600Difficulty Graphs 20 questions
  6. bbs.FISHC.com//python_文件
  7. 华为数通考试正式改版,改版前后有什么区别?
  8. ps,pr,ae安装插件出现“无法加载扩展,因为它未正确签署”解决办法
  9. python读取文件报错OSError: [Errno 22] Invalid argument: '\u202aC:\\Users\\yyqhk\\Desktop\\1.csv'
  10. AR law : Privacy
  11. Matlab计算质心
  12. Spark 写入 MySQL 乱码问题
  13. android本地商城,Android本地商城应用
  14. 使用ThreeJs从零开始构建3D智能仓库——第四章(添加动画及库区)
  15. 90后成电信诈骗重灾区 为什么年轻人越来越容易被骗?
  16. 国产EUV光刻机再进一步,已拿下20多项专利,ASML后悔莫及
  17. 大数据可以揭示基因密码吗?
  18. FIR数字滤波器在DSP芯片C2000上的实现
  19. python web Android屏幕录制
  20. 数据安全能力成熟度模型DSMM----2、数据采集安全

热门文章

  1. classpath目录
  2. jquery.autocomplete自动补齐和自定义格式
  3. Android开源git40个App源码
  4. POJ 1014 Dividing
  5. 3.3 修改“时间”维度
  6. 锋利的Jquery摘要
  7. eclipse项目两个红点
  8. 一 对国家出路的早期探索
  9. 机器学习 - 支持向量机
  10. JAVA工具类-StrUtils