
提要
本文提出了一种全新的数据结构树的存储方法,即围棋树存取方法,该存储方法是独创的、颠覆性的,完全打破了几十年以来一直压在数据结构树头上的诸多桎梏,将长期压在它头上的存储和存取效率低下的恶名,彻底抛到九霄云外。
围棋树存储方法的主要特点有:
为树的每个节点编制了一套智能化的三维数字坐标,使得所有的树的存储变得有序和收敛且可以使用效率更高的类似于二叉树的方法来存储,从而为树的优化和管理采用数字化的解决方案提供了有力的保障。正是每个节点的三维数字坐标,使得整棵树不再是一个僵硬的层次化的存储块,而变成可以简便操作的数据库表结构,树中的每个节点可以灵活地存放到关系数据库中,节点与节点的关系变成松耦合的线性关系且可以完全用数字来表达和计算,这就为节点的高效存取奠定了坚实的基础,也为人工智能在数据结构树领域的应用埋下了伏笔。
我们知道,关系数据库在存储大量数据方面有很多的有效方法,比如,分区、分表和分库。此外,我们在分布式存储和数据中心建设方面也积累了很多的经验,这样,当我们将树存放到关系数据库后,我们就再也不用担心某些需要存储大量数据的业务场景,比如,国家图书馆目录检索系统,它们的存储问题了。我们相信,围棋树算法的提出,将为我国各类大型查询检索系统的提出,提供有力的保障。
为了验证围棋树算法的可行性,我们使用Python和Mysql数据库开发了一套围棋树的应用接口(API),提供了各种应用场景需要调用的功能,并运用这些接口完成了围棋树算法的原型测试(POC),在此基础上,我们还完成了围棋树的存储压力测试和存取压力测试,既验证了围棋树在存储大型树数据方面的卓越性能,也验证了围棋树在高效存取方面的优异表现,从而证明了围棋树在对传统树结构数字化方面的尝试是完全成功的。
接《围棋树是如何解决树的诸多问题的 - Part 1 of 5》
第二节 围棋树实现的应用接口API和调用方法
(一)围棋树开发环境及数据库表设计
围棋树的应用接口API是使用Python开发的,数据库使用Windows下的MySQL,主要包括核心模块gotree.py和一部分已经写好的函数,用户只要将这些模块导入(import)到自己的应用程序中,就可以方便地使用围棋树应用接口API了。当然,各种应用系统功能各不相同,它们的实现还要应用系统自己完成。
图8. 围棋树Mysql表结构围棋树的数据存储采用的是Windows下的Mysql数据库,其性能跟Mysql数据库有紧密的关系。围棋树使用的表结构如图8所示。其中,开始的6列是围棋树特有的字段,用来给传统的树结构做数字化编码,即将每个节点定位到围棋棋盘的行和列交叉点上。前面的3列(rw,cl,ovcl)分别定义每个节点本身的行、列和溢出列,它们在整颗树里面必须是唯一的,因为我们需要将它们定义为主键(PRIMARY KEY)。接下来的3个字段(frw,fcl,fovcl)则定义其父节点的坐标,即父节点的行、列和溢出列。这6个字段是围棋树的灵魂,也是围棋树具备超越传统树性能的核心所在。
字段ndname和fndname分别定义的是节点本身的名字和其父节点的名字,节点名字要求在整颗树里面是唯一的,不可重复的,因此,我们将它定义为唯一索引
(UNIQUE INDEX)。由于一个父节点可以有多个子节点,因此,父节点在整颗树里面是可以重复出现的,为了提高访问的效率,我们将其定义成了可重复索引(INDEX)。
字段ndname和fndname只是由于所处的位置不同,导致有二个字段存在,它们分别表示节点本身的名字和父节点的名字,但它们的格式必须是一样的,对于围棋树来说,它们的格式是没有强制规定的,完全可以根据应用的需要来自由定义。比如,对于族谱应用来说,由于所管理的都是家族中的人,因此,节点名ndname可以定义为姓名+身份证号,对于其它应用来说,可以根据其需要自由定义,围棋树算法对其不做任何特殊要求。最后一个字段nddata用来存放节点数据,完全是给应用系统使用的,采用围棋树作为载体的应用,可以自由定义它们的数据格式并映射到这个字段中。这个字段的格式和长度完全由应用系统决定,围棋树接口会在每次操作完成后返回相应的数据给应用系统处理。
不同的应用系统对信息的要素组成和格式是不同的,比如,湖北稻香文化发展有限公司有多年的族谱系统应用和推广经验,他们的族谱信息非常详尽,如图9所示。要把这些跟应用系统息息相关的信息放到围棋树中显然不是一个好的设计!所以我们建议,在围棋树的nddata字段存放族谱详细信息的关键字,比如,姓名+身份证号,作为访问族谱信息的索引,而族谱详细信息则单独存放到另一个Mysql数据库表中。
图9. 族谱详细信息(二)建立吴国国王孙坚家谱树的围棋树
将传统的树放到围棋棋盘并采用我们介绍的围棋树算法后,我们很容易获得每个树节点的坐标,因而可以用这些坐标来表达各个节点在树中的位置。在采用三维坐标(行、列、溢出列)并经过反复的研究和算法的验证之后,我们使用Python语言,完成了应用系统接口API的开发。
围棋树作为一种数据结构树的底层实现方法,可以作为目前使用树结构的应用系统,比如,家(族)谱、公司组织架构、图书馆图书管理系统等的载体,供各类应用系统使用。他们只需要了解下一节提供的应用接口API的调用方法,就可以轻松完成自己的应用开发了。
现在,我们使用已经开发完成的围棋树API接口,将上文中图7所示的吴国国王孙坚家谱树的围棋树建立起来,即存放到图8所示的Mysql数据库表gotree_tb01中。首先,我们把孙坚家族树的节点关系,用Excel表示出来,这个应该很好理解,结果如图10所示:
图10. 孙坚家族树,Excel表示,输入然后,我们调用Excel文件转围棋树API接口excel2tree(filename,headers=1),将Excel文件的内容加载到MySQL数据库表gotree_tb01中, 具体的调用命令如下,其各个参数的含义可以参考本章第五小节《围棋树应用接口API清单及调用参数说明》中的描述:
#=========从Excel文件生成围棋树==============
filename='D:\gotree_data\gotreesun.xlsx' headers=1
excel2tree(db_connect_parm,tablename,filename,headers=1)
接口命令执行完后,数据库表gotree_tb01中的内容如图11所示。从图11的数据库表中,我们看到,它的内容比Excel多了好几列,这些内容就是围棋树为每个节点编制的三维坐标,其中,三维坐标(rw,cl和ovcl)是节点本身的三维坐标,而三维坐标(frw,fcl和fovcl)则是给它的父节点编制的,它的作用相当于指向父节点的指针。

图11. 孙坚家族树,根据图10的Excel表生成的围棋树,对应的数据库表的内容
孙坚是根节点,它的坐标为(1,1,0),没有父节点,因此,我们统一将根节点的父节点的坐标设置为(0,0,0)。
孙策是孙坚第一个儿子,按照围棋树的生成规则,它是孙策的左子节点,因此,它的坐标为(2,1,0),父节点为孙坚的节点坐标,即(1,1,0)。孙权是孙坚的第二个儿子,同样按照围棋树的生成规则,它是孙策的右子节点,因此,它的坐标为(2,2,0),父节点同样为孙坚的节点坐标,即(1,1,0)。
同样是孙坚的儿子,孙翊和孙匡只能作为孙坚的中子节点,它们的父节点坐标同样也是孙坚的节点坐标(1,1,0),但它自身节点的坐标则比较独特,分别为(2,1,439009322)和(2,1,992496678),它们的行号都是2,即(1+1),表示是根节点的下一层节点;列的值都为1,即(2*1-1),溢出列ovcl的值比较突兀,是一个很大的数,这是因为我们采用无符号整数作为溢出列的取值范围而导致的,它是随机数,是为了解决节点坐标冲突而引进的特别坐标,具体的取值是多少并不重要,重要的是,它必须能够保证三维坐标在整颗树里面是唯一的。

图12. 孙坚家族树,从图11的数据库表下载下来的Excel表的内容
实际上,作为应用开发者,是不需要了解围棋树的三维坐标的,因为对于他们是透明的,他们只要使用我们提供的API接口,专注与应用功能的开发就可以了,围棋树底层的结构,由我们专业的团队维护就可以了。这一点从图12也可以得到验证,它是从数据库表中下载下来的孙坚家族树的数据,供应用开发者备份和维护的,里面也没有三维坐标。