随着互联网的兴起, 传统的关系型数据库在应付web2.0网站, 特别是超大规模和高并发类型的网站应用时, 显得有些无能为力, 而非关系型数据的管理技术现已成为一个极其热门的新领域[1]。作为非关系型数据的典型存储和管理模型, NoSQL[1-3]技术已得到了快速发展。NoSQL数据库管理技术的特点主要是基于“键-值对”(key-value) 数据模型来进行数据管理, 它打破了传统的关系模型, 以一种模式自由的方式存储数据, 提供了新型的访问接口, 并克服了传统关系型数据库管理模型的缺点[2-3]。NoSQL数据库在互联网、电子商务、电信、金融、安全、教育、大数据、原子能以及移动计算等诸多领域得到了广泛应用。因此, 对其进行相关研究具有学术意义和实用价值。
MongoDB[4]是一款功能强、灵活且易于进行扩展的NoSQL类型的数据库管理系统, 现已得到广泛应用。与此同时, 由于MongoDB数据库不具备标准的SQL访问接口, 因此, 业内熟悉标准SQL的开发人员在使用其应用程序接口 (application program interface, API) 进行系统设计时, 不但学习困难繁琐, 而且需要编写很多行程序, 开发效率低。为了解决这个问题, 本文基于ANTLR[5]编译器辅助工具, 提出了一种针对MongoDB数据库的SQL转化模型, 并对其原型实现进行了评估, 这对于降低程序员学习MongoDB数据库的难度, 提高其开发效率具有重要意义和实用价值。
为MongoDB数据库增加SQL访问接口, 会涉及许多方面的关键技术。目前, 一些学者采用了不同的方法试图解决这个问题 (参见本文的“相关研究”部分)。在以下几个方面, 本文与这些学者的研究成果存在显著不同:①采用的技术路线不同;②SQL解析和语义转换方法不同;③模型性能差异大。
1 SQL转化模型构成基于ANTLR的MongoDB数据库SQL转化模型构成如图 1所示, 它建立在操作系统和MongoDB数据库管理系统等底层之上, 可以将SQL、原生的MongoDB API和封装的MongoDB API作为模型的输入, 而这些输入的返回结果是其输出。
![]() |
图 1 SQL转化模型构成示意图 |
在SQL转化模型内部, 主要包括API调度层、SQL解析层、语义转换层以及运行支撑层等4个层次。
API调度层主要为用户提供了3大类API调用方法, 分别与输入类型相对应。当用户输入类型为SQL时, API调度层首先通过SQL解析层将输入的SQL转化为具体的语言对象, 然后, 再通过语义转换层将具体的语言对象转化为封装的MongoDB API调用 (位于运行支撑层, 是对原生的MongoDB API的再次封装), 最后, 通过调用原生的MongoDB API (位于运行支撑层, 由MongoDB驱动程序提供) 来获得返回的执行结果。
当用户输入类型为原生的MongoDB API和封装的MongoDB API时, API调度层不会调用SQL解析层和语义转换层, 而是分别调用位于运行支撑层的原生MongoDB API和封装MongoDB API来实现对MongoDB数据库的操作。
运行支撑层中包括属性配置、MongoDB数据库连接池、ANTLR运行库、MongoDB驱动程序以及封装的MongoDB API等部分, 为上层功能提供支持, 并通过MongoDB驱动程序与MongoDB数据库管理系统进行数据交互。
2 SQL解析SQL解析层主要包括词法分析、语法分析、SQL分析、树遍历器、对象化封装以及错误处理等部分 (如图 2所示)。
![]() |
图 2 SQL解析层组成示意图 |
按照ANTLR规定的语法规则, 将SQL规范转变为SQL语法文件, ANTLR据此生成词法分析器和语法分析器。
词法分析器的输入是SQL字符串, 其输出是词语类型 (ANTLR称之为token)。而语法分析器则会使用这些词语类型和语法规则, 将用户输入的SQL字符串转化为抽象语法树 (abstract syntax tree, AST)。当然, 在语法分析器的工作过程中, 会产生和使用一些辅助的数据结构、字符表和流程图数据等。
SQL分析模块通过调用树遍历器, 获取SQL字符串中的各个组成部分, 并将结果存储在辅助的数据结构当中。
对象化封装模块通过访问SQL分析模块产生的辅助的数据结构, 将SQL最终封装为由具体计算机语言描述的语言对象, 例如, 可以将用户输入的SQL字符串中的select语句单独封装为一个Java语言对象, 其他部分可以类推。
在SQL解析层工作过程中, 错误处理模块负责各种异常情形的处理。
3 语义转换如图 3所示, 语义转换层主要由语义检查、参数生成、API调用以及错误处理等部分组成, 其输入为与用户输入的SQL对应的语言对象 (即经过SQL解析层处理后的输出, 参见图 2), 输出为封装的MongoDB API调用。
![]() |
图 3 语义转换示意图 |
语义检查模块主要负责对上层产生的语言对象进行各种合法性检查。例如, 在where子句中, 当字段类型不是字符串类型时, 就不能使用like关键字。
参数生成模块的主要功能在于抽取每种SQL语句的各个组成部分所对应的参数, 并将这些参数转化为封装的MongoDB API对应的参数对象。例如, 在处理由select语句形成的语言对象时, 就需要处理from子句、where子句、order by子句以及limit子句等部分对应的参数对象。
根据不同类型的SQL语句产生的语言对象及其参数对象的差异, API调用模块分别调用封装的不同种类的MongoDB API, 完成对MongoDB数据库的操作。
在语义转换层工作过程中, 错误处理模块负责各种异常情形的处理。
4 运行机制基于ANTLR的MongoDB数据库SQL转化模型的运行机制如图 4所示, 按照时间先后顺序, 大致可以分为准备、启动和转换3个阶段。
![]() |
图 4 运行机制示意图 |
1) 准备阶段:由系统管理人员对MongoDB数据库进行权限设置, 并将用户名称、密码、数据库服务器IP地址、端口号以及默认的数据库名称等各种参数写进配置文件中。
2) 启动阶段:启动系统, 完成配置参数的加载和数据库连接池的启动。
3) 转换阶段:接受用户的系统调用, 并且将响应结果返回。
5 相关研究在国内, 刘冠[6]通过为每种SQL语句定制正则表达式的方法来实现对SQL的解析, 然后, 通过扩展XQuery来实现对MongoDB数据库的操作。这种方法的局限是对SQL的解析很繁琐, 同时, 对MongoDB的操作需要经过XQuery的再次转换。
郑小裕[7]采用的方案是:首先, 需要用户构建复合查询语言作为输入; 然后, 模型将复合查询语言转换为等价的SQL语句; 最后, 将转换后的SQL语句发送到SQL数据库中执行。其中, SQL执行时, MongoDB数据由框架转换为三元组注入到SQL数据库中。这种方法需要用户熟悉复合查询语言, 同时, 转换过程也比较复杂, 可能会导致整体的数据访问性能不高。
在国外, mongo-jdbc[8]是一个开源的、实验性的MongoDB数据库驱动程序, 采用开源SQL解析器JSqlParser来实现对用户输入的SQL语句的解析, 再经过语义转换来实现对MongoDB数据库的操作。经过对其源程序的研究, 发现其功能过于简单 (例如, 不能实现多个条件的数据处理)。同时, 由于JSqlParser能够对常用的一些SQL语句进行解析, 但兼容的语法有限, 比如括号, 或者一些复杂的结构等。因此, 这种方法不能实现对SQL的灵活处理, 其扩展性受到限制。另外, 它是以JDBC (Java data base connectivity) 驱动程序的方式提供, 模型中不提供数据库连接池, 这对模型的性能会产生比较大的影响。
文献[9]只是很简略地描述了使用SQL作为输入, 通过元数据层来完成从SQL到MongoDB数据库API的转换, 但怎么解析SQL和如何转换, 该文献语焉不详。
与文献[9]类似, 文献[10]也只是简要描述, 并没有具体阐述SQL的解析方法和转换方法。与文献[9]不同的是, 文献[10]从宏观上提出了虚拟执行引擎的概念, 实现SQL到MongoDB数据库API的转换。
文献[11]定义了一个新的语言SQL++, 通过它来解析用户的具体输入, 再经过虚拟数据库的转换, 实现对MongoDB数据库的操作。这种方法实现比较复杂, 对用户来说, 需要学习SQL++的具体语法。
6 效果验证按照本文描述的转化模型, 采用Java语言, 实现了一个初始版本的系统原型。为了对模型的性能进行评估, 并且便于与已有文献中所提出的模型的性能进行对比, 主要选取了在软件开发过程中最常用的几种数据操作类型。
测试环境如下:
处理器:英特尔i5-3210M, 2.50GHz, 双核。
内存:4GB (DDR3, 1 600MHz)。
硬盘:希捷ST1000LM024HN-M101MBB, 容量1TB。
操作系统:Windows7旗舰版, 64位, SP1。
MongoDB数据库:3.07。
JDK: 1.7, 64位。
对原型系统性能的评估结果如表 1所示, 并对所取得的评估数据进行了分析。
序号 | 操作类型 | 单次平均响应时间/μs | 操作延迟 | ||
MongoDB API | 原型系统 | ΔT/μs | 延迟/% | ||
1 | 插入 | 229 | 262 | 33 | 12.6 |
2 | 查询 | 11 | 42 | 31 | 73.8 |
3 | 修改 | 6 892 | 6 929 | 37 | 0.5 |
4 | 删除 | 6 696 | 6 745 | 49 | 0.7 |
为了便于进行比较, 将一万次同类型的数据访问操作所消耗的时间/μs, 再除以总的操作次数后所获得的时间作为比较的依据, 简称为单次平均响应时间。
不论使用原生的MongoDB API进行测试, 还是使用本转化模型的原型系统进行测试, 修改和删除2种操作所消耗的单次平均响应时间最长, 达到将近7 ms, 查询操作所花费的单次平均响应时间最少, 只有11~42 μs, 而插入操作所使用的单次平均响应时间也较少, 大约为229~262 μs。
相对于使用原生的MongoDB API进行测试, 采用本转化模型的原型系统进行测试时, 会产生操作延迟 (我们使用ΔT表示)。4种基本操作类型所产生的操作延迟比较接近, 大约为31~49 μs, 这主要是由模型中的SQL解析层产生的。从实际使用的感受来说, 用户不会感到明显延迟。
相对于原型系统中的单次平均响应时间, 将延迟时间所占的比率称为延迟百分比。修改和删除操作所对应的延迟百分比最小, 可以忽略不计; 而查询操作的延迟百分比最大, 达到了73.8%, 原因是由于查询操作本身所对应的单次平均响应时间非常短暂引起的。
7 结论通过分析著名的NoSQL数据库MongoDB的特点, 为了克服其缺乏SQL访问接口的缺限, 本文提出了一种基于ANTLR的MongoDB数据库SQL转化模型, 并对该模型的分层构成、SQL解析、语义转换以及运行机制进行了重点研究。为了对该模型的效果进行评估, 设计开发了该模型的初始版本的原型系统。通过评估数据可以看出, 延迟时间近似为一个31~49 μs的常数, 达到了预期的目标。另外, 该原型系统也在实际的智慧城市建设项目中得到了初步应用, 降低了软件开发人员的学习成本, 提高了工作效率。下一步, 将基于该模型, 在原型系统中实现更多的新特性。
[1] |
李莉莎.
关于NOSQL的思考[J]. 中国传媒科技, 2010 (4): 40–41.
Li Lisha. Thinking about NOSQL[J]. Science & Technology for China's Mass Media, 2010(4): 40–41. (in Chinese) |
[2] |
申德荣, 于戈, 王习特, 等.
支持大数据管理的NoSQL系统研究综述[J]. 软件学报, 2013, 24 (8): 1786–1803.
Shen Derong, Yu Ge, Wang Xite, et al. Survey on NoSQL for Management of Big Data[J]. Journal of Software, 2013, 24(8): 1786–1803. (in Chinese) |
[3] | Pokorny J. NoSQL Databases:a Step to Database Scalability in Web Environment[J]. International Journal of Web Information Systems, 2013, 9(1): 69–82. DOI:10.1108/17440081311316398 |
[4] | Chodorow K, Dirolf M. MongoDB:The Definitive Guide[M]. 2nd Ed. O'Reilly Media Inc: USA, 2013. |
[5] | Terence Parr. The Definitive ANTLR 4 Reference[M]. The Pragmatic Programmers: USA, 2012. |
[6] |
刘冠. 标准SQL语句与MongoDB数据转换技术研究[D]. 成都: 四川师范大学, 2013
Liu Guan. Research on Data Conversion Technology from Standard SQL to MongoDB[D]. Chengdu, Sichuan Normal University, 2013(in Chinese) |
[7] |
郑小裕. SQL与NoSQL数据库的统一查询模型的研究与实现[D]. 长沙: 湖南大学, 2014
Zheng Xiaoyu. Research and Implementation of Unified Query Model about Relation Database and Non-Relation Database[D]. Changsha, Hunan University, 2014(in Chinese) |
[8] | 10gen Inc. mongo-jdbc[EB/OL]. (2010-02-09)[2016-04-20]. https://github.com/erh/mongo-jdbc |
[9] | Khan S, Mane P V. SQL Support over MongoDB Using Metadata[J]. International Journal of Scientific and Research Publications, 2013, 3(10): 1–5. |
[10] | Lawrence R. Integration and Virtualization of Relational SQL and NoSQL Systems Including MySQL and MongoDB[C]//International Conference on Computational Science and Computational Intelligence, 2014:285-290 |
[11] | Ong K W, Papakonstantinou Y, Vernoux R. The SQL++Unifying Semi-Structured Query Language, and an Expressiveness Benchmark of SQL-on-Hadoop, NoSQL and NewSQL Databases[EB/OL]. (2014-05-14)[2016-04-20]. http://arxiv.org/pdf/1405.3631v8.pdf |