正文
视频教程:https://doc.iocoder.cn/video/
闭包表通常是一个包含两个主要列的表:祖先列和后代列。每一行记录都表示一对节点之间的关系,其中祖先列存储父节点(或祖先节点)的标识,后代列存储子节点(或后代节点)的标识。通过在闭包表中插入适当的记录,可以建立节点之间的所有直接和间接关系。
使用闭包表可以快速地确定一个节点的所有祖先节点和后代节点。例如,要查询一个节点的所有后代节点,只需在后代列中查找包含该节点标识的记录。要查询一个节点的所有祖先节点,只需在祖先列中查找包含该节点标识的记录。
闭包表的结构和查询方式使得树的遍历和查询操作变得高效。它避免了在树结构中进行递归或迭代遍历的复杂性,通过简单的数据库查询语句即可完成。
闭包表还具有灵活性和可扩展性。当需要添加、删除或移动节点时,只需对闭包表进行相应的插入、删除或更新操作,而无需修改树结构本身。这种设计使得闭包表适用于动态变化的树结构。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
-
项目地址:https://github.com/YunaiV/yudao-cloud
-
视频教程:https://doc.iocoder.cn/video/
在闭包表(Closure Table)的设计中,有几个关键角色扮演重要的作用:
-
节点(Node):
节点是树结构中的元素或实体,可以是任何具体的对象,如组织机构中的部门、分类体系中的分类、评论树中的评论等。每个节点在闭包表中都有唯一的标识符。
-
关系表(Closure Table):
关系表是存储节点之间关系的表格。它包含两个主要列:祖先列和后代列。每一行记录都表示节点之间的关系,其中祖先列存储父节点(或祖先节点)的标识,后代列存储子节点(或后代节点)的标识。
-
闭包(Closure):
闭包是指节点之间的直接和间接关系的集合。通过闭包表,可以通过查询祖先列或后代列来获取某个节点的闭包。闭包包含了节点的所有祖先节点和后代节点。
-
祖先节点(Ancestor):
祖先节点是指一个节点的直接或间接上级节点。在闭包表中,通过查询祖先列可以获得一个节点的所有祖先节点。
-
后代节点(Descendant):
后代节点是指一个节点的直接或间接下级节点。在闭包表中,通过查询后代列可以获得一个节点的所有后代节点。
假设有一个组织结构的树形菜单,每个菜单项代表一个部门或子部门,其中包含部门名称和部门ID。我们可以使用闭包表来表示树形结构中的节点关系,并实现分页查询。
下面是一个使用闭包表实现树形结构数据的分页查询的案例。
首先,我们创建部门信息表
CREATE TABLE `departments` (
`id` int NOT NULL COMMENT 'ID',
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部门名称',
`parent_id` int DEFAULT NULL COMMENT '父ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='部门表';
然后,我们创建闭包表
CREATE TABLE `departments_closure_table` (
`ancestor` int NOT NULL COMMENT '祖先节点',
`descendant`