新闻详情

新闻详情

首页 / 资讯中心 / 详情

经典树形结构:闭包表

发布时间:2026/9/27 10:58:49来源:尧图网络
经典树形结构:闭包表
一、树形结构存储难在哪树形结构由节点和边组成每个节点可以有零个或多个子节点但只有一个父节点根节点除外。这种结构在现实中随处可见公司的组织架构、电商的商品类目、论坛的帖子回复……但在关系型数据库中存储和查询它们却并不直观。常见的诉求无非就几类查某个节点的所有子节点、查所有祖先节点、查两节点之间的距离、增删改节点。看似简单但不同的存储方案在这几项操作上的表现天差地别。二、四种常见方案速览在正式介绍闭包表之前我们先快速了解另外三种主流方案这样才能理解闭包表到底“优”在哪里。1. 邻接表最直观的方案——每个节点记录一个parent_id指向父节点。优点结构简单插入方便。缺点查询子树或祖先需要递归查询层级深时性能极差。2. 路径枚举在每个节点中存储从根节点到该节点的完整路径如/1/2/3。优点避免了递归查询查询子树效率高。缺点移动节点时需要更新该节点及所有子孙的路径维护成本极高路径长度有上限。3. 嵌套集为每个节点赋予左右值通过数值范围来判断祖先后代关系。优点查询子树极快。缺点插入、删除、移动节点时需要更新大量节点的左右值模型复杂维护困难。4. 闭包表——今天的主角单独创建一张关系表存储树中所有节点对之间的祖先-后代关系包括节点自身。三、闭包表的核心原理闭包表的核心思想是空间换时间——用额外的存储空间换取查询效率的大幅提升。它通常需要两张表节点表存储节点本身的信息CREATE TABLE nodes ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL );闭包关系表存储所有祖先-后代关系CREATE TABLE node_paths ( ancestor_id INT, -- 祖先节点ID descendant_id INT, -- 后代节点ID depth INT, -- 两者之间的距离层数差 PRIMARY KEY (ancestor_id, descendant_id), FOREIGN KEY (ancestor_id) REFERENCES nodes(id), FOREIGN KEY (descendant_id) REFERENCES nodes(id) );关键点每个节点不仅要记录与所有祖先的关系还要记录与自身的关系即ancestor_id descendant_iddepth 0。举个例子假设有这样一棵树1 ├── 2 │ └── 4 └── 3闭包表中存储的数据是这样的ancestor_iddescendant_iddepth110121131142220241330440有了这张表查询就变得异常简单查询节点1的所有后代SELECT * FROM node_paths WHERE ancestor_id 1查询节点4的所有祖先SELECT * FROM node_paths WHERE descendant_id 4查询节点2的直接子节点SELECT * FROM node_paths WHERE ancestor_id 2 AND depth 1四、闭包表的优缺点优点查询效率极高无论树有多深查询任意节点的所有祖先或所有后代都只需要一次简单的索引查询无需递归。支持复杂查询可以轻松查询两节点之间的距离、某个节点的所有子孙等。节点移动方便移动一个子树时只需要删除该子树相关的旧路径再插入新路径即可操作相对可控。缺点存储空间较大闭包表存储了所有节点对的关系数据量约为 O(n²) 级别。树越大关系表膨胀越明显。插入成本较高插入一个新节点时需要为它和所有祖先节点各插入一条关系记录。五、什么时候该用闭包表综合来看闭包表最适合以下场景树形结构层级较深比如超过5层邻接表的递归查询难以承受。查询操作远多于写入操作愿意用存储空间换取查询性能。需要频繁查询祖先/后代关系比如权限系统中的部门归属查询、电商系统中的类目路径查询。如果树结构非常浅、数据量很小或者写入极其频繁邻接表可能是更轻量的选择。没有银弹只有最适合的方案。六、总结闭包表通过“空间换时间”的思路用一张专门的关系表存储所有节点对的祖先-后代关系将复杂的树形查询转化为简单的索引查询。虽然插入和存储成本有所增加但在查询性能和维护便利性上优势明显。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

3家定制高端网站建设企业对比评测,解决没流量痛点 2026/9/27 11:50:04

3家定制高端网站建设企业对比评测,解决没流量痛点

3家定制高端网站建设企业对比评测,解决没流量痛点 网站做好了没人访问,这是最扎心的现实。很多老板花大价钱找公司定制高端网站建设企业,上线后打开率却惨不忍睹。别急,问题往往出在选型和SEO底层逻辑上。今天我不讲虚的,直接拿三家在湖北武汉及周边…

阅读更多 →
STM32开发避坑指南:从时钟树到外设调试的实践经验 2026/9/27 11:49:57

STM32开发避坑指南:从时钟树到外设调试的实践经验

STM32这个系列我前前后后用了六七年,从最早的F103标准库一路做到H743的HAL工程,产品级的东西交付过不少,板子上翻过车的事情也多得数不清。如果你让我总结一句最真实的感受,那就是:STM32本身并不难,难的是那…

阅读更多 →
BugKu——请攻击这个压缩包(明文攻击) 2026/9/27 11:49:57

BugKu——请攻击这个压缩包(明文攻击)

一、题目 二、方法 下载得到一个zip压缩包,压缩需要密码,预览里面有一张png图片,使用7z查看图片的加密方式。 ZipCrypto是zip传统的加密方式,它有一个致命弱点:它用的是流密码思路,密钥流只由 3 个 32 位状…

阅读更多 →
IT66612深度解析:HDMI信号再生原理与工程实践 2026/9/27 11:49:57

IT66612深度解析:HDMI信号再生原理与工程实践

1. 为什么IT66612不是“一分二”的简单搬运工,而是HDMI信号再生的精密手术刀你拆开市面上那些标着“HDMI一分二有源分配器”的小盒子,十有八九会看到一块印着IT66612字样的黑色芯片。但如果你真以为它只是把一根HDMI线的信号原封不动地“复制粘贴”到两根…

阅读更多 →
Hermes 上下文压缩架构拆解:长任务 Agent 不失忆的 ContextEngine 与 ContextCompressor 关键设计 2026/9/27 11:49:51

Hermes 上下文压缩架构拆解:长任务 Agent 不失忆的 ContextEngine 与 ContextCompressor 关键设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
网站建设更新踩坑实录:新手入门必看的3个救命细节 2026/9/27 11:49:51

网站建设更新踩坑实录:新手入门必看的3个救命细节

网站建设更新踩坑实录:新手入门必看的3个救命细节 网站上线三个月,后台流量却只有个位数,你是不是也急得抓耳挠腮?很多新手入门建站的朋友,花大价钱做了官网,结果上线后就像石沉大海,没人看、没人点,连百度收录都慢得让人怀疑人生。其实,问题往往不…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉