树形结构数据存储方案(一):邻接列表模式

2017 年 8 月 30 日 数据库开发

(点击上方公众号,可快速关注)


来源:标点符

www.biaodianfu.com/adjacency-list.html

如有好文章投稿,请点击 → 这里了解详情


在程序开发中,我们常遇到用树型结构来表示某些数据间的关系,如企业的组织架构、商品的分类、操作栏目等,目前的关系型数据库都是以二维表的形式记录存储数据,而树型结构的数据如需存入二维表就必须进行Schema设计。最近对此方面比较感兴趣,专门做下梳理,如下为常见的树型结构的数据:



其中最简单的方法是:Adjacency List(邻接列表模式)。简单的说是根据节点之间的继承关系,显现的描述某一节点的父节点,从而建立二位的关系表。表结构通常设计为{Node_id,Parent_id},如下图:



使用连接表的大致代码:


<?php

// $parent is the parent of the children we want to see

// $level is increased when we go deeper into the tree,

//        used to display a nice indented tree

function display_children($parent, $level)

{

   // 获得一个 父节点 $parent 的所有子节点

   $result = mysql_query('SELECT name FROM tree WHERE parent="'.$parent.'";');

   // 显示每个子节点

   while ($row = mysql_fetch_array($result))

   {

       // 缩进显示节点名称

       echo str_repeat('  ',$level).$row['name']."\n";

       //再次调用这个函数显示子节点的子节点

      

       display_children($row['name'], $level+1);

   }

}

?>


对整个结构的根节点(Food)使用这个函数就可以打印出整个多级树结构,由于Food是根节点它的父节点是空的,所以这样调用: display_children(”,0)。将显示整个树的内容。如果你只想显示整个结构中的一部分,比如说水果部分,就可以这样调用:display_children(‘Fruit’,0);


几乎使用同样的方法我们可以知道从根节点到任意节点的路径。比如 Cherry 的路径是 ”Food >; Fruit >; Red”。 为了得到这样的一个路径我们需要从最深的一级”Cherry”开始, 查询得到它的父节点”Red”把它添加到路径中, 然后我们再查询Red的父节点并把它也添加到路径中,以此类推直到最高层的”Food”


以下是代码:


<?php

// $node 是那个最深的节点

function get_path($node)

{

   // 查询这个节点的父节点

   $result = mysql_query('SELECT parent FROM tree '.

                          'WHERE name="'.$node.'";');

   $row = mysql_fetch_array($result);

   // 用一个数组保存路径

   $path = array();

   // 如果不是根节点则继续向上查询

   // (根节点没有父节点)

   if ($row['parent']!='')

   {

       // the last part of the path to $node, is the name

       // of the parent of $node

       $path[] = $row['parent'];

       // we should add the path to the parent of this node

       // to the path

       $path = array_merge(get_path($row['parent']), $path);

   }

   // return the path

   return $path;

}

?>


如果对”Cherry”使用这个函数:print_r(get_path(‘Cherry’)),就会得到这样的一个数组了:


Array  

(  

  [0] =>; Food  

  [1] =>; Fruit  

  [2] =>; Red  

)


这种方案的优点很明显:结构简单易懂,由于互相之间的关系只由一个parent_id维护,所以增删改都是非常容易,只需要改动和他直接相关的记录就可以。缺点当然也是非常的突出:由于直接地记录了节点之间的继承关系,因此对Tree的任何CRUD操作都将是低效的,这主要归根于频繁的“递归”操作,递归过程不断地访问数据库,每次数据库IO都会有时间开销。举个例子,如果想要返回所有水果,也就是水果的所有子孙节点,看似很简单的操作,就需要用到一堆递归。当然,这种方案并非没有用武之地,在树的层级比较少的时候就非常实用,在邻接列表模式的基础上还可以拓展的是平面表,区别是将节点的level和当前节点的顺序也放入表中,比较适合类似评论等场景,具体的表结构类似这样,这里就不再深入阐述。



参考链接:


  • http://salman-w.blogspot.com/2012/08/php-adjacency-list-hierarchy-tree-traversal.html

  • https://packagist.org/search/?tags=adjacency%20list



看完本文有收获?请转发分享给更多人

关注「数据库开发」,提升 DB 技能

登录查看更多
0

相关内容

专知会员服务
42+阅读 · 2020年7月7日
[ICML2020]层次间消息传递的分子图学习
专知会员服务
33+阅读 · 2020年6月27日
元学习与图神经网络逻辑推导,55页ppt
专知会员服务
128+阅读 · 2020年4月25日
【ICLR2020-哥伦比亚大学】多关系图神经网络CompGCN
专知会员服务
49+阅读 · 2020年4月2日
【ICLR2020-】基于记忆的图网络,MEMORY-BASED GRAPH NETWORKS
专知会员服务
108+阅读 · 2020年2月22日
近期必读的12篇KDD 2019【图神经网络(GNN)】相关论文
专知会员服务
62+阅读 · 2020年1月10日
六篇 CIKM 2019 必读的【图神经网络(GNN)】长文论文
专知会员服务
37+阅读 · 2019年11月3日
论文浅尝 | ICLR2020 - 基于组合的多关系图卷积网络
开放知识图谱
21+阅读 · 2020年4月24日
Cayley图数据库的可视化(Visualize)
Python开发者
5+阅读 · 2019年9月9日
文本分析与可视化
Python程序员
9+阅读 · 2019年2月28日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
干货 | Python 爬虫的工具列表大全
机器学习算法与Python学习
10+阅读 · 2018年4月13日
在NLP中深度学习模型何时需要树形结构?
全球人工智能
5+阅读 · 2018年3月29日
Python 爬虫实践:《战狼2》豆瓣影评分析
数据库开发
5+阅读 · 2018年3月19日
Neo4j 和图数据库起步
Linux中国
8+阅读 · 2017年12月20日
python pandas 数据处理
Python技术博文
4+阅读 · 2017年8月30日
Meta-Learning with Latent Embedding Optimization
Arxiv
6+阅读 · 2018年7月16日
Arxiv
4+阅读 · 2018年2月19日
VIP会员
相关VIP内容
专知会员服务
42+阅读 · 2020年7月7日
[ICML2020]层次间消息传递的分子图学习
专知会员服务
33+阅读 · 2020年6月27日
元学习与图神经网络逻辑推导,55页ppt
专知会员服务
128+阅读 · 2020年4月25日
【ICLR2020-哥伦比亚大学】多关系图神经网络CompGCN
专知会员服务
49+阅读 · 2020年4月2日
【ICLR2020-】基于记忆的图网络,MEMORY-BASED GRAPH NETWORKS
专知会员服务
108+阅读 · 2020年2月22日
近期必读的12篇KDD 2019【图神经网络(GNN)】相关论文
专知会员服务
62+阅读 · 2020年1月10日
六篇 CIKM 2019 必读的【图神经网络(GNN)】长文论文
专知会员服务
37+阅读 · 2019年11月3日
相关资讯
论文浅尝 | ICLR2020 - 基于组合的多关系图卷积网络
开放知识图谱
21+阅读 · 2020年4月24日
Cayley图数据库的可视化(Visualize)
Python开发者
5+阅读 · 2019年9月9日
文本分析与可视化
Python程序员
9+阅读 · 2019年2月28日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
干货 | Python 爬虫的工具列表大全
机器学习算法与Python学习
10+阅读 · 2018年4月13日
在NLP中深度学习模型何时需要树形结构?
全球人工智能
5+阅读 · 2018年3月29日
Python 爬虫实践:《战狼2》豆瓣影评分析
数据库开发
5+阅读 · 2018年3月19日
Neo4j 和图数据库起步
Linux中国
8+阅读 · 2017年12月20日
python pandas 数据处理
Python技术博文
4+阅读 · 2017年8月30日
Top
微信扫码咨询专知VIP会员