一种基于邻接表实现节点路径的查询方法及系统
技术领域
本发明涉及数据存储领域,更具体地说,涉及一种基于邻接表实现节点路径的查询方法及系统。
背景技术
树形结构是计算机信息系统的一种常用表示方法,可以很方便地展示实体之间的关系(例如:商品分类、文件系统、人员的组织架构)。树形结构的基本操作为增加节点、删除节点、移动子树、获取节点路径等。
目前比较经典和普遍的存储方式有以下几种,各自都有相应的缺陷:
1、邻接表(Adjacency List):保存父子相邻节点的关系;当获取一个节点的路径时,需要每一层查询一次父节点,当层级较多时,查询的次数会相应增多。
2、路径枚举(Path Enumerations):保存每个节点到根节点之间经过的节点枚举;当移动一个比较大的子树时,需要修改子树中每个节点的路径信息;当子树较大时,此操作会花费较多时间。
3、嵌套集(Nested Sets):每个节点使用nleft和nright来编码,其中nleft比所有后代都小,nright比所有后代都大。当插入和移动节点时,需要重新分配左右值,会花费较多时间。
4、闭包表(Closure Table):将树中所有节点间的关系都记录下来;此方法需要的存储空间较大,并且移动子树需要修改的行数较多。
上述几种数据存储方式中,在树的深度比较深的情况下,“移动子树”和“获取节点路径”这两种操作中只能有一种能够快速完成。
发明内容
本发明要解决的技术问题在于,针对现有技术数据查询效率较低的缺陷,通过在邻接表的基础上增加了一个路径缓存算法,实现节点路径的快速查询方法。
本发明解决其技术问题所采用的技术方案是:构造一种基于邻接表实现节点路径的查询方法,包括以下步骤:
S1、定义第一集合A1和第二集合A2;其中,所述第一集合A1中包括了若干个已查询节点,所述第二集合A2中包括了若干个待查询节点;
S2、查询缓存系统:在缓存系统中,查询所述第二集合A2中所有待查询节点的祖先节点;
S3、将步骤S2中查询到的祖先节点,与第一集合A1中所有的已查询节点进行匹配,将未匹配成功的祖先节点作为待查询节点存入第二集合A2中;
S4、在数据库中查询所有待查询节点的直接父节点,并将查询到对应直接父节点的待查询节点作为查询节点,存入到第一集合A1中;
S5、清空第二集合A2中的节点数据;
S6、将步骤S4中查询到的所有直接父节点,存入所述已清空的第二集合A2中;
S7、重复步骤S2至S6,直到第二集合A2为空时,执行步骤S8;
S8、利用第一集合A1中的节点数据进行节点路径查询。
进一步的,步骤S1中,将能够从数据库中查询到父节点的节点作为已查询节点,将未能从数据库中查询到父节点的节点作为待查询节点。
进一步的,在数据库中以邻接表的方式存储整个树的节点相邻关系;
进一步的,步骤S2采用的缓存系统,以键-值对的方式记录每个节点,以及与节点相对应的祖先节点;其中,将以节点作为键,以节点的祖先列表作为值,所述祖先列表中包括了与节点相对应的若干个祖先节点。
进一步的,当第二集合A2为空时,即所述第二集合A2中的待查询节点均通过查询数据库找到其对应的直接父节点,此时根据第一集合A1中的查询节点和与其相对应的祖先节点,即可得到每个已查询节点的查询路径。
进一步的,当第二集合A2为空时,将第一集合A1中的每个查询节点作为键,所述每个查询节点的祖先列表作为值,写入到缓存系统中,使得在下次进行节点路径查询的时候,还能够利用之前写入的缓存数据,减少总体查询次数。
本发明提供的另外一种基于邻接表实现节点路径的查询系统,包括以下模块:
缓存模块,用于存储节点以及每个节点相对应的祖先节点;
数据库模块,用于以邻接表的方式存储整个树的节点相邻关系;
路劲查询模块,用于利用数据库模块和缓存模块中存储的节点数据,进行节点路径查询。
进一步的,所述查询系统利用如前述任意一项的节点路劲方法步骤,实现节点的路劲查询。
在本发明所述的一种基于邻接表实现节点路径的查询方法即系统中,在邻接表的基础上增加一个路径缓存,能够将之前的多次查询变成批量查询,减少查询直接父节点的次数,当层级较多时也能够快速查询路径。
本发明提出的技术方案不仅能够节省存储空间,还能够使移动子树和查询路径都有较好的性能;其中,移动子树的操作只需修改数据库中的邻接表而不需要更新缓存;查询路径操作中每个节点的父节点都是从数据库中查询,以此来保证路径查询的正确性;另一方面当缓存与数据库一致时,无论树有多深,由于缓存中已经有了每个节点的全部祖先节点,只需对数据库做一次批量查询来确认缓存一致,即可获得每个节点的路径。
附图说明
下面将结合附图及实施例对本发明作进一步说明,附图中:
图1是实现节点路径查询的方法流程图;
图2是整个树的结构图;
图3是树结构对应的领接表图;
图4是缓存系统中保存的部分节点的祖先节点列表图;
图5是实施过程图;
图6是最终需要查询的节点路径图;
图7是缓存系统更新图;
图8是节点路径查询系统的原理结构图。
具体实施方式
为了对本发明的技术特征、目的和效果有更加清楚的理解,现对照附图详细说明本发明的具体实施方式。
请参考图1,其为实现节点路径查询的方法流程图,作为一个示例,请参考图2和图3,其分别为数据库中存储的整个树的结构图,以及与其对应的邻接表图。从图2中可知,本实施例中,在数据库中存储了8个节点,分别为节点1001-节点1008,通过图3中提供的与树结构所对应的邻接表可知,当前树结构中的子节点,以及与子节点所对应的父节点。
本发明提供的一种基于邻接表实现节点路劲查询的方法,具体包括以下步骤:
S1、定义第一集合A1和第二集合A2;其中,所述第一集合A1中包括了若干个已查询节点,所述第二集合A2中包括了若干个待查询节点;其中,将能够从数据库中查询到父节点的节点作为已查询节点,将未能从数据库中查询到父节点的节点作为待查询节点。作为一个示例,以节点1001作为要查询路径的节点,将节点1001放入第二集合A2中。
S2、查询缓存系统:在缓存系统中,查询集合A2中节点1001的祖先节点,其中,本实施例采用的缓存系统,以键-值对的方式记录每个节点,以及与节点相对应的祖先节点;其中,将以节点作为键,以节点的祖先列表作为值,所述祖先列表中包括了与节点相对应的若干个祖先节点;
请参考图4,其为缓存系统中保存的部分节点的祖先节点列表图,其中从图中可直观的得出每个节点对应的祖先节点,且允许部分缓存项与实际情况不一致。
S3、将步骤S2中查询到的祖先节点,与第一集合A1中所有的已查询节点进行匹配,将未匹配成功的祖先节点作为待查询节点存入第二集合A2中。
S4、在数据库中查询所有待查询节点的直接父节点,并将查询到直接父节点的待查询节点作为查询节点,存入到第一集合A1中。
S5、清空第二集合A2中的节点数据;
S6、将步骤S4中查询到的若干个直接父节点,存入所述已清空的第二集合A2中;
S7、重复步骤S2至S6,直到第二集合A2为空时,执行步骤S8;请参考图5,其为实施过程图,在本示例中,经过两次循环后,第二集合A2为空,即所述第二集合A2中的待查询节点均通过查询数据库找到其对应的直接父节点。
S8、利用第一集合A1中的节点数据进行节点路径查询,此时根据第一集合A1中的查询节点和与其相对应的祖先节点,即可得到每个节点的查询路径。请参考图6,其为最终需要查询的节点路径图,即本实施例中从根节点1001到其对应祖先节点1007的查询路径,图中可见在依次经过节点1002、节点1003节点1005后,最终查询到祖先节点1007。
本实施例中,为了提高算法的查询效率,在执行步骤S8时,将第一集合A1中的每个查询节点作为键,所述每个查询节点的祖先列表作为值,写入到缓存系统中;这样就保证了在下次运行时,还能够利用上次执行算法式写入的缓存数据,使得在查询数据库时能够一次查询多个待查询节点的直接父节点,减少总体查询次数。在本示例中,利用图4所示的不完全正确的缓存作为提示,只对数据库进行了两次查询就完成了深度为5的路径查询,结束后将正确的祖先节点写入缓存系统中,具体请参见图6所示的缓存系统更新图。
请参考图8,其为节点路径查询系统的原理结构图,本发明提供的一种基于邻接表实现节点路径的查询系统,包括缓存模块L1、数据库模块L2以及路劲查询模块L3,其中:
缓存模块L1用于存储节点以及每个节点相对应的祖先节点;
数据库模块L2用于以邻接表的方式存储整个树的节点相邻关系;
路劲查询模块L3用于利用数据库模块和缓存模块中存储的节点数据,进行节点路径查询。
所述节点路径查询系统,利用如前述任一项路径查询方法进行节点路径查询。
上面结合附图对本发明的实施例进行了描述,但是本发明并不局限于上述的具体实施方式,上述的具体实施方式仅仅是示意性的,而不是限制性的,本领域的普通技术人员在本发明的启示下,在不脱离本发明宗旨和权利要求所保护的范围情况下,还可做出很多形式,这些均属于本发明的保护之内。