起因

在最近的工作中,有一个需求: 前端需要通过多种不同的字段组合查询某项配置表, 返回所有满足条件的表项。

这个需求的实现难点在于,可选的字段有很多个,最多会达到十几项,而且匹配不一定准确查找,可能是模糊查找。可能需要这种查找的表项也不止有一张,可能有多张。

看到这个需求,首先想到的是自己去写代码去做,多个字段都缓存到内存之中,批量对各个字段进行查询匹配之后取交集。这样尽管能完成需求,但是执行效率会很慢。因为要读出所有数据进行处理。代码量也会很大,因为难以提取通用组件,要逐个模块去逐个字段去处理。

然后想到的是使用SQL数据库,利用SQL语言成熟的建模机制和数据查询分析方法,达到多字段查询的目的。这种想法初看很美好,把复杂查询转化为sql语句。但是动手实施的时候马上遇到了多表联合查询的问题。本来我们的配置数据以json的形式存储,没有使用数据库表,非常简便,不用为各种复杂嵌套的数据结构和只有一条表项的全局配置创建表项是一件很幸福的事情。但现在要使用sql了,必须为各种嵌套的数据结构设计多张表。为了查询更快,还要创建索引。更糟糕的,需要多次join联合,才能完成一次查询,join查询写起来麻烦,性能也不高。综合来说,这是用数据库来做一种它不太擅长的工作。

既然SQL数据库做这项工作不擅长,那有没有合适的工具或者库,可以更方便的完成这项工作呢?关键是容易与我们现有的这套系统结合。

我广泛调研了mongodb,elasticsearch, dgraph等nosql实现。其中elasticsearch很快pass,消耗资源太多,而且跟我们的C/GO技术栈不符合。

剩下mongodb和dgraph,一个是文档数据库,一个图数据库,看起来都能满足我们的需求,需要进一步比较。

mongodb 与 dgraph

安装与运维

两者都有开源的安装包,相比而言dgraph是static链接的单个可执行文件,mongodb还有些依赖,dgraph略胜一筹。

数据分析能力

两者都比较容易实现多字段查询这一需求,而且支持对字段进行正则查找。 因为两者存储格式的差异,图数据库在关系组合分析方面更胜一筹。

而mongodb在字符串分析方面更强一些。整体而言,图数据库略微胜出。

易用性

mongodb使用bson进行基本的数据操作,bson是binary json,很容易转换。复杂一些的组合操作也比较容易做。整体易用性高。

dgraph操作数据的基本格式是rdf和json,rdf用于scheme,json用于crud。组合操作靠graphql和dql两种操作语言。

整体而言,mongodb的操作方式更简易。

性能

需要对CPU和内存使用情况进行深入验证,待补充。