在数据库中存储层次型数据

本文探讨了在数据库中存储层次型数据的两种常见方法:邻接表和改进前序遍历树,分析了各自的优势和缺点。通过实验发现,尽管改进前序遍历树在算法上更复杂,但在效率上与邻接表相差不大。文章提出了折衷方案——改进邻接表,并指出邻接表的主要耗时在于数据库查询,而改进前序遍历树则涉及层次判断。
摘要由CSDN通过智能技术生成

前言

层次型数据在数据库中的存储已经是老生常谈,常见的: 

  1. 邻接表
  2. 改进前序遍历树

下面我将简要介绍这两种方法的思路并附上代码,然后会探讨两种方法的优劣,以及背后原因,最后提出一种折衷的办法:改进邻接表。

 


 

方法一:邻接表

假设我们需要在数据库中存储如下的结构

 

(图片来自:参考1)

 

那么使用邻接表将会在数据库中这么存放数据:

 

(图片来自:参考1)

 

表结构很简单明了,值得一提的是实际项目中parent一般是写id号的,这里只是为了可读性。

那么我们从数据库中恢复树状结构只要使用递归的方法,代码如下

 

 1 #coding=utf-8
2
3 import sqlite3 as lite
4 import time
5
6 if __name__ == "__main__":
7
8 con = lite.connect('data.sqlite3')
9 allline = con.execute("select * from foods").fetchall()
10
11 def show_item(parent, level):
12 sql = "select * from foods where parent='%s' " % parent
13 cur = con.execute(sql)
14 for one in cur.fetchall():
15 print '---'*level + one[1]
16 show_item(one[1], level+1)
17
18 show_item('food',0)

 

很明显,这种方法主要的时间都耗在递归和递归中的查询,具体哪个是主要原因目前还不得知,不过在下文我们将会刨根究底。 

 


 

方法二:改进前序遍历树

数据库中的存储结构,和邻接表对比发现,少了parent,多了left和right。这left和right是怎么来的呢?

 

 

 主要思路如下图所示:

 

(图来自参考1)

 

我们希望将树状结构用水平结构来表示,按照如图所示的路线进行标注。

首先在food的左边标1,然后fruit左边标2,如此下去,我们发现这样一种结构

 

 

,最上方的粗线就是food,第二行的第一根是fruit,第二根是meat,这样看是不是觉得把树状结构用在数轴上表示出来了?

那么遍历这样一种结构十分方便,如果我们要查找food的字节点,那么只要

 

select * from foods where left > 1 and right < 18 order by left

“order by left”刚好就是按照正常的顺序进行排列,剩下一个问题就是缩进!?

解决办法就是运用stack:访问到哪个节点,如果发现节点的right比栈顶的大,那么出栈,直到栈顶比节点的right小,然后只要计算栈的大小就是缩进的长度了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值