树形结构的各个存取方案对比--《sql反模式》


树
在这里插入图片描述

问题

需要存储树型结构的数据, 比如存储公司组织架构, 或论坛的评论区. 如何设计库表

下面提供多种方案并分析各方案的优缺点

  1. 邻接表
  2. 递归查找
  3. 路径枚举
  4. 嵌套集
  5. 闭包集

(具体的库表方案需要结合具体业务 , 充分考虑各个方案的优缺点后选择 , 没有万能的方案 , 也不要过度设计)

邻接表

简介

最容易想到的方式就是邻接表了(单表, 每行存储一个parentId外键).
(因为节点与父节点属于多对一关系, 所以在多的一方存储外键).
表结构如下:(tree表)

id node_info parent_id
1 根节点… 0
2 第一层节点… 1

优势

  1. 库表结构简单直观
  2. 查询直接父节点或直接子节点简单(inner join 或 子查询等)
  3. 插入单个节点简单(只需设置新节点的parentId, 并更新子节点的parentId)

劣势

  1. 查询某节点的 子树 麻烦. 比如想一次性看到某部门的所有子部门
  2. 查询某节点的 所有父节点 麻烦
  3. 删除 子树 麻烦, 比如想删除某评论以及该评论延伸的所有子评论(有点绕)

邻接表适用于层次比较少且基本不扩展的树型结构.(比如省/市/县的存取)

递归查询

简介

递归查询就是在邻接表的基础上改良的(解决劣势问题).
邻接表 在查询节点的子树或节点的所有父节点麻烦, 那么 递归查询 的做法就是创建DB的函数实现递归查找.
下图是查询某个节点的所有孩子节点的DB函数(查询节点的所有父节点类似)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值