今天介绍将树形结构存储在数据库中的第三种方法——终结表(原谅我这生硬的翻译。。)。node
继续用上一篇的栗子,下面是要存储的结构图:数据库
须要回答的问题依旧是这样几个:spa
1.查询小天的直接上司。翻译
2.查询老宋管理下的直属员工。3d
3.查询小天的全部上司。code
4.查询老王管理的全部员工。blog
方案3、Closure Table 终结表法,保存每一个节点与其各个子节点的关系,也就是记录以其为根节点的所有子节点信息。直接上代码就明白了:索引
这里要建立两个表,一个表用来存储信息:同步
CREATE TABLE employees3( eid INT, ename VARCHAR(100), position VARCHAR(100) )
一个表用来存储关系:博客
CREATE TABLE emp_relations( root_id INT, depth INT, is_leaf TINYINT(1), node_id INT )
这里的root_id用来存放以其为根节点的路径,node_id表示节点处的eid,depth表示根节点到该节点的深度,is_leaf表示该节点是否为叶子节点。
接下来插入数据:
能够看出,这个关系表有点大,咱们先来看看查询效果如何:
1.查询小天的直接上司。
这里只须要在关系表中找到node_id为小天id,depth为1的根节点id便可。
SELECT e2.ename BOSS FROM employees3 e1,employees3 e2,emp_relations rel WHERE e1.ename='小天' AND rel.node_id=e1.eid AND rel.depth=1 AND e2.eid=rel.root_id
查询结果以下:
2.查询老宋管理下的直属员工。
思路差很少,只要查询root_id为老宋eid且深度为1的node_id即为其直接下属员工id
SELECT e1.eid,e1.ename 直接下属 FROM employees3 e1,employees3 e2,emp_relations rel WHERE e2.ename='老宋' AND rel.root_id=e2.eid AND rel.depth=1 AND e1.eid=rel.node_id
查询结果以下:
3.查询小天的全部上司。
只要在关系表中找到node_id为小天eid且depth大于0的root_id便可
SELECT e2.eid,e2.ename 上司 FROM employees3 e1,employees3 e2,emp_relations rel WHERE e1.ename='小天' AND rel.node_id=e1.eid AND rel.depth>0 AND e2.eid=rel.root_id
查询结果以下:
4.查询老王管理的全部员工。
只要在关系表中查找root_id为老王eid,depth大于0的node_id便可
SELECT e1.eid,e1.ename 下属 FROM employees3 e1,employees3 e2,emp_relations rel WHERE e2.ename='老王' AND rel.root_id=e2.eid AND rel.depth>0 AND e1.eid=rel.node_id
查询结果以下:
咱们能够发现,这四个查询的复杂程度是同样的,这就是这种存储方式的优势,并且可让另外一张表只存储跟节点紧密相关的信息,看起来更简洁。但缺点也显而易见,关系表会很庞大,当层次很深,结构很庞大的时候,关系表数据的增加会愈来愈快,至关于用空间效率来换取了查找上的时间效率。
至此,树形结构在数据库中存储的三种方式就介绍完了,接下来对比一下三种方法:
方案一:Adjacency List
优势:只存储上级id,存储数据少,结构相似于单链表,在查询相邻节点的时候很方便。添加删除节点都比较简单。
缺点:查询多级结构的时候会显得力不从心。
适用场合:对多级查询需求不大的场景比较适用。
方案二:Path Enumeration
优势:查询多级结构的时候比较方便。查询相邻节点时也比较ok。增长或者删除节点的时候比较简单。
缺点:须要存储的path值可能会很大,甚至超过设置的最大值范围,理论上没法无限扩张。
适用场合:结构相对简单的场景比较适合。
方案三:Closure Table
优势:在查询树形结构的任意关系时都很方便。
缺点:须要存储的数据量比较多,索引表须要的空间比较大,增长和删除节点相对麻烦。
适用场合:纵向结构不是很深,增删操做不频繁的场景比较适用。
固然,也能够再本身创新出其余更好的存储方案,若是有更好的想法,欢迎提出交流。
至此三种方案所有介绍完毕,欢迎你们继续关注。
个人博客即将同步至腾讯云+社区,邀请你们一同入驻。