最近在弄个分佣项目,一开始使用了之前转载的那个path方式来做,但使用后发现这个方式不太合适用来做各种级差、分销、无限等分佣方式,然后百度一下午,终于找到了一个非常不错的建立上下级关系方法,ClosureTable。

ClosureTable直译过来叫闭包表?不过不重要,ClosureTable以一张表存储节点之间的关系、其中包含了任何两个有关系(上下级)节点的关联信息

定义关系表CategoryTree,其包含3个字段:

ancestor 祖先:上级节点的id
descendant 子代:下级节点的id
distance 距离:子代到祖先中间隔了几级

这三个字段的组合是唯一的,因为在树中,一条路径可以标识一个节点,所以可以直接把它们的组合作为主键。以图为例,节点6到它上一级的节点(节点4)距离为1在数据库中存储为ancestor=4,descendant=6,distance=1,到上两级的节点(节点1)距离为2,于是有ancestor=1,descendant=6,distance=2,到根节点的距离为3也是如此,最后还要包含一个到自己的连接,当然距离就是0了。

子节点查询

查询id为5的节点的直属子节点:

SELECT descendant FROM CategoryTree WHERE ancestor=5 AND distance=1

查询所有子节点:

SELECT descendant FROM CategoryTree WHERE ancestor=5 AND distance>0

查询某个上级节点的子节点,换句话说就是查询具有指定上级节点的节点,也就是ancestor字段等于上级节点id即可,第二个距离distance决定了查询的对象是由上级往下那一层的,等于1就是往下一层(直属子节点),大于0就是所有子节点。这两个查询都是一句完成。

路径查询

查询由根节点到id为10的节点之间的所有节点,按照层级由小到大排序

SELECT ancestor FROM CategoryTree WHERE descendant=10 ORDER BY distance DESC

查询id为10的节点(含)到id为3的节点(不含)之间的所有节点,按照层级由小到大排序

SELECT ancestor FROM CategoryTree WHERE descendant=10 AND
distance<(SELECT distance FROM CategoryTree WHERE descendant=10 AND ancestor=3)
ORDER BY distance DESC

查询路径,只需要知道descendant即可,因为descendant字段所在的行就是记录这个节点与其上级节点的关系。如果要过滤掉一些则可以限制distance的值。

查询节点所在的层级(深度)

查询id为5的节点是第几级的

SELECT distance FROM CategoryTree WHERE descendant=5 AND ancestor=0

查询id为5的节点是id为10的节点往下第几级

SELECT distance FROM CategoryTree WHERE descendant=5 AND ancestor=10

查询层级(深度)非常简单,因为distance字段就是。直接以上下级的节点id为条件,查询距离即可。

查询某一层的所有节点

查询所有第三层的节点

SELECT descendant FROM CategoryTree WHERE ancestor=0 AND distance=3

插入

插入和移动就不是那么方便了,当一个节点插入到某个父节点下方时,它将具有与父节点相似的路径,然后再加上一个自身连接即可。

所以插入操作需要两条语句,第一条复制父节点的所有记录,并把这些记录的distance加一,因为子节点到每个上级节点的距离都比它的父节点多一。当然descendant也要改成自己的。

例如把id为10的节点插入到id为5的节点下方(这里用了Mysql的方言)

INSERT INTO CategoryTree(ancestor,descendant,distance) (SELECT ancestor,10,distance+1 FROM CategoryTree WHERE descendant=5)

然后就是加入自身连接的记录。

INSERT INTO CategoryTree(ancestor,descendant,distance) VALUES(10,10,0)

移动

节点的移动没有很好的解决方法,因为新位置所在的深度、路径都可能不一样,这就导致移动操作不是仅靠UPDATE语句能完成的,这里选择删除+插入实现移动。

另外,在有子树的情况下,上级节点的移动还将导致下级节点的路径改变,所以移动上级节点之后还需要修复下级节点的记录,这就需要递归所有下级节点。
删除id=5节点的所有记录

DELETE FROM CategoryTree WHERE descendant=5

然后配合上面一节的插入操作实现移动。具体的实现直接上代码吧。

上面讲的是方法,还需要自己去理解,实际的去使用!

ClosureTable 用户上下级有关系的建立和使用相关推荐

  1. 如何建立用户之间的邀请关系 / 邀请注册机制

    假如张三的用户编号是 1234 ,那么张三邀请的用户,如何和张三建立邀请关系呢? 用户之间的邀请关系是在注册那一刻建立的,建立后,不会因为任何原因发生改变: 新用户在注册的时候,所有的注册api接口, ...

  2. 多对多关系需要建立中间表_【数据库基础】为什么需要三张表之多对多表结构设计...

    了解完一对一和一对多表结构设计,接下来一起了解一下多对多的表结构设计. 同样,咱们先来想一般什么场景需要用到多对多.假如说咱们有一个叫订单和一个叫商品的这两张表,这两张表的关系,它其实就是一个多对多的 ...

  3. 用户体验改善案例_用户体验案例研究:建立更好的体验(重新设计“和平航空”网站)...

    用户体验改善案例 by Peace Ojemeh (Perrie) 由Peace Ojemeh(Perrie) 用户体验案例研究:建立更好的体验(重新设计"和平航空"网站) (A ...

  4. linux系统解锁用户百度,详细到没朋友,一文帮你理清Linux 用户与用户组关系~

    原标题:详细到没朋友,一文帮你理清Linux 用户与用户组关系~ 1.用户和用户组文件 在 linux 中,用户帐号,用户密码,用户组信息和用户组密码均是存放在不同的配置文件中的. 在 linux 系 ...

  5. OSPF协议原理及配置4-邻接关系的建立和LSDB同步

    OSPF协议原理及配置4-邻接关系的建立和LSDB同步 进入ExStart状态后,广播和NBMA型网络要等待4倍的Hello时间,确定DR和BDR.然后建立邻接关系,并交互链路状态通告,以使用LSDB ...

  6. OSPF 总结—— ospf邻居关系无法建立原因 + OSPF选路影响因素

    目录 一.ospf邻居关系无法建立原因: 二.选路影响因素: (1)宏观: (2)微观: 一.ospf邻居关系无法建立原因: 1--直接链路没有ping通 2--接口过滤OSPF的hello报文 3- ...

  7. 武汉新时标文化传媒有限公司抢夺用户最关键的是建立用户认知

    一. 抢用户,抢夺时间:讨好年轻人 互联网的竞争就是用户的抢夺之战--用户就那么多,用户的时间就那么多. 玩抖音的人多了,玩微信的就少了:玩抖音的时间多了,玩微信的时间就少了.这是一群荷尔蒙过剩的年轻 ...

  8. C语言,英文小写转大写,小写字母转换成大写字母通过大小写字母间的ASCII值的关系来建立代码

    #include <stdio.h> int main() {char a,b;scanf("%c",&a);b=a-32;printf("%c&qu ...

  9. 一对一、一对多、多对多模型关系的建立和增删改查要注意的问题

    一对一.一对多.多对多模型关系的建立和增删改查要注意的问题 一对一: 1.在维护关系的一方使用:models.OneToOneField(另一个一方模型类名称,on_delete=models.CAS ...

最新文章

  1. 《C#与.NET3.5高级程序设计(第4版)》笔记10
  2. win10+vs2017 snmp开发实例
  3. 大数据互联网架构阶段 Linux下安装mysql启动的常见问题
  4. java反编译,eclipse支持插件
  5. redhat9Linux解压gz,linux (redhat9)下subversion 的安装
  6. Android之常见面试题
  7. c++--运算符重载
  8. 创建单IP的***网络
  9. Docker-Compose快速部署开源网盘系统Tank蓝眼网盘系统
  10. Redis缓存安装Version5.0.7
  11. win8超极本盘符误删找回数据的办法
  12. dll可以在linux下使用吗_Linux下使用rm删除文件,并排除指定文件
  13. 利用RecyclerView实现无限轮播广告条
  14. clion开发php,如何在 Mac 上用 Clion 调试 php7 源码
  15. 全面的软件测试-软件测试图解
  16. 后摩尔时代下先进封装技术
  17. vue中前端怎么读取txt文本文档?
  18. 弗曼学习法,你在用吗?
  19. 恢复SVN的Replacing操作
  20. 机器人搭建记录 yobot(LinuxWindows手动搭建)

热门文章

  1. Excel列批量插入公式
  2. 威马EX5上路实测:车标、智能旋转屏等具有辨识度 但部分配置尚存提升空间
  3. 分量视频 Y'UV, YUV, YCbCr,YPbPr
  4. Android入门项目(六)Android的wifi开发,androidwifi开发教程
  5. 罗马复兴各民族兵种详细参数——腓尼基篇
  6. Hadoop Failed to set permissions of path 错误处理
  7. makefile之override
  8. ESXI6.7网卡驱动封装之离线封装-(转载)
  9. matlab标定的焦距和实际的不一样,摄像机标定中焦距,尺度因子,传感器尺寸,图像分辨率关系。...
  10. python对maya绑定的作用_Python加速绑定Maya教程 CGCircuit – Rigging Productivity Boost