python模型管道函数 python管道阻塞( 四 )


这样我们会意识到,SQL 作为查询语言 , 它只是对二维数据表这种结构而设计的,用它去查询图的话非常笨拙,很快会变得极其复杂,也难以扩展 。针对图而言,我们希望有一种更为自然和直观的查询语法,类似这样:
为了高效地存储和查询图这种数据结构,图数据库( Graph Database )应运而生 。因为和传统的关系型数据库存在极大的差异,所以它属于新型数据库也就是 NoSql 的一个分支(其他分支包括文档数据库、列数据库等) 。图数据库的主要代表包括 Neo4J 等 。本文介绍的 Dagoba 则是具备图数据库核心功能、主要用于教学和演示的一个简单的图数据库 。
原文代码是使用JavaScript 编写的 , 在定义调用接口时大量使用了原型( prototype )这种特有的语言构造 。对于其他主流语言的用户来说 , 原型的用法多少显得有些别扭和不自然 。
考虑到本系列其他数据库示例大多是用Python 实现的 , 本文也按照传统 , 用 Python 重写了原文的代码 。同样延续之前的惯例,为了让读者更好地理解程序是如何逐步完善的,我们用迭代式的方法完成程序的各个组成部分 。
原文在500lines 系列的 Github 仓库中只包含了实现代码,并未包含测试 。按照代码注释说明,测试程序位于作者的另一个代码库中,不过和 500lines 版本的实现似乎略有不同 。
本文实现的代码参考了原作者的测试内容,但跳过了北欧神话这个例子——我承认确实不熟悉这些神祇之间的亲缘关系,相信中文背景的读者们多数也未必了解 , 虽然作者很喜欢这个例子,想了想还是不要徒增困惑吧 。因此本文在编写测试用例时只参考了原文关于家族亲属的例子 , 放弃了神话相关的部分,尽管会减少一些趣味性,相信对于入门级的代码来说这样也够用了 。
本文实现程序位于代码库的dagoba 目录下 。按照本系列程序的同意规则,要想直接执行各个已完成的步骤 , 读者可以在根目录下的 main.py 找到相应的代码位置,取消注释并运行即可 。
本程序的所有步骤只需要Python3  , 测试则使用内置的 unittest , 不需要额外的第三方库 。原则上 Python3.6 以上版本应该都可运行,但我只在 Python3.8.3 环境下完整测试过 。
本文实现的程序从最简单的案例开始 , 通过每个步骤逐步扩展,最终形成一个完整的程序 。这些步骤包括:
接下来依次介绍各个步骤 。
回想一下 , 图数据库就是一些点( node )和边( edge )的集合 。现在我们要做出的一个重大决策是如何对节点/边进行建模 。对于边来说,必须指定它的关联关系,也就是从哪个节点指向哪个节点 。大多数情况下边是有方向的——父子关系不指明方向可是要乱套的!
考虑到扩展性及通用性问题 , 我们可以把数据保存为字典( dict ),这样可以方便地添加用户需要的任何数据 。某些数据是为数据库内部管理而保留的,为了明确区分,可以这样约定:以下划线开头的特殊字段由数据库内部维护,类似于私有成员,用户不应该自己去修改它们 。这也是 Python 社区普遍遵循的约定 。
此外,节点和边存在互相引用的关系 。目前我们知道边会引用到两端的节点,后面还会看到,为了提高效率,节点也会引用到边 。如果仅仅在内存中维护它们的关系,那么使用指针访问是很直观的,但数据库必须考虑到序列化到磁盘的问题,这时指针就不再好用了 。
为此,最好按照数据库的一般要求 , 为每个节点维护一个主键( _id ),用主键来描述它们之间的关联关系 。

推荐阅读