什么是Calcite

  Apache Calcite是一个动态数据管理框架,它具备很多典型数据库管理系统的功能,比如SQL解析、SQL校验、SQL查询优化、SQL生成以及数据连接查询等,但是又省略了一些关键的功能,比如Calcite并不存储相关的元数据和基本数据,不完全包含相关处理数据的算法等。

  也正是因为Calcite本身与数据存储和处理的逻辑无关,所以这让它成为与多个数据存储位置(数据源)和多种数据处理引擎之间进行调解的绝佳选择。

  Calcite所做的工作就是将各种SQL语句解析成抽象语法树(AST Abstract Syntax Tree),并根据一定的规则或成本对AST的算法与关系进行优化,最后推给各个数据处理引擎进行执行。

  目前,使用Calcite作为SQL解析与优化引擎的又Hive、Drill、Flink、Phoenix和Storm,Calcite凭借其优秀的解析优化能力,会有越来越多的数据处理引擎采用Calcite作为SQL解析工具。

  Calcite 主要功能

  Calcite的主要功能我们上面其实已经提到了,主要有以下功能:

  SQL解析:通过JavaCC将SQL解析成未经校验的AST语法树

  SQL校验:校验分两部分,一种为无状态的校验,即验证SQL语句是否符合规范;一种为有状态的即通过与元数据结合验证SQL中的Schema、Field、Function是否存在。

  SQL查询优化:对上个步骤的输出(RelNode)进行优化,得到优化后的物理执行计划

  SQL生成:将物理执行计划生成为在特定平台/引擎的可执行程序,如生成符合Mysql or Oracle等不同平台规则的SQL查询语句等

  数据连接与执行:通过各个执行平台执行查询,得到输出结果。

  所以在Calcite中,一条SQL的处理步骤就很清晰了,那么我们通过Calcite的代码来实际了解一下:

  // 初始化配置

  SqlParser.ConfigBuilder configBuilder = SqlParser.configBuilder();

  configBuilder.setUnquotedCasing(Casing.UNCHANGED);

  //Sql解析:解析Sql语句,通过JavaCC解析成AST语法树,表现为SqlNode

  SqlParser sqlParser = SqlParser.create(sql, configBuilder.build());

  SqlNode sqlNode = sqlParser.parseQuery();

  //Sql校验:结合元数据信息验证Sql是否符合规范

  Planner planner = Frameworks.getPlanner(config);

  SqlNode node = planner.validate(sqlNode);

  //Sql查询优化:将SqlNode转换为LogicalPlan,表现为RelNode

  RelRoot relRoot = planner.rel(node);

  RelNode project = relRoot.project();

  //指定优化规则

  final HepProgram program = new HepProgramBuilder()

  .addRuleInstance(SubQueryRemoveRule.PROJECT)

  .addRuleInstance(SubQueryRemoveRule.FILTER)

  .addRuleInstance(SubQueryRemoveRule.JOIN)

  .build();

  //生成优化后的RelNode

  HepPlanner prePlanner = new HepPlanner(program);

  prePlanner.setRoot(project);

  RelNode relNode = prePlanner.findBestExp();

  //ToDo 执行查询

  使用Calcite

  那么前面对Calcite进行了简单的介绍,我们如何使用Calcite呢?Calcite的使用非常简单,你要做的只是添加数据源即可。我们以Mysql数据源为例,我们通过添加Mysql数据库作为Calcite的数据源,实现通过Calcite对Mysql数据进行查询的Demo。

  //创建Calcite Connection对象

  Class.forName(org.apache.calcite.jdbc.Driver);

  Properties info = new Properties();

  info.setProperty(lex, JAVA);

  Connection connection =

  DriverManager.getConnection(jdbc:calcite:, info);

  CalciteConnection calciteConnection =

  connection.unwrap(CalciteConnection.class);

  SchemaPlus rootSchema = calciteConnection.getRootSchema();

  //创建Mysql的数据源schema

  Class.forName(com.mysql.jdbc.Driver);

  BasicDataSource dataSource = new BasicDataSource();

  dataSource.setUrl(jdbc:mysql://localhost);

  dataSource.setUsername(username);

  dataSource.setPassword(password);

  Schema schema = JdbcSchema.create(rootSchema, hr, dataSource,

  null, name);

  rootSchema.add(hr, schema);

  //执行查询

  Statement statement = calciteConnection.createStatement();

  ResultSet resultSet = statement.executeQuery(

  select d.deptno, min(e.empid)\n

  + from hr.emps as e\n

  + join hr.depts as d\n

  + on e.deptno = d.deptno\n

  + group by d.deptno\n

  + having count(*) 1);

  print(resultSet);

  resultSet.close();

  statement.close();

  connection.close();

  Calcite提供了多种方式添加数据源,如通过“inline:”的字符串方式以及通过json或yaml文件的方式。同时,Calcite抽象出了功能齐全的接口,可以方便的将CSV文件抽象成数据表进行查询。这部分内容可以通过官方的示例了解一下!

  当然SQL解析、校验与执行计划优化是Calcite的基本功能,Calcite的NB之处在于,Calcite的目标是“one size fits all”,希望能为不同的计算平台和数据源提供统一的查询引擎,并且以类似传统数据库的访问方式(SQL)来访问Hadoop上的数据。所以Calcite提供了非常丰富的可扩展接口,帮助我们实现扩展数据源、扩展针对不同数据源的优化规则、扩展SQL查询语法、扩展数据处理引擎等等。这部分后面会详细介绍(挖坑ing)

最新文章

  1. Web Service概念梳理
  2. BZOJ1269——[AHOI2006]文本编辑器editor
  3. PhpStorm 2016.3 For Mac 重大里程碑更新 -- 终于解决了不能输入中文标点符号的重大bug
  4. Hyper-V初涉_Hyper-V虚拟机文件交换
  5. PHPExcel使用体会
  6. 计划将项目中使用entity framework的要点记录到改栏目下
  7. JNI技术基础(1)——从零开始编写JNI代码
  8. LInux : du命令
  9. Eclipse Ctrl+Tab Alt+/ 快捷键
  10. 初识hibernate
  11. spring集成Apache的ActiveMQ
  12. android源码编译环境的准备及编译之后使用emulator运行的方法 - 官方版
  13. Linux系统编程(13)——Shell的基本语法
  14. 【LeetCode】【Python解读】Container with most water
  15. SpringMvc+thymeleaf+HTML5中文乱码问题
  16. 从零开始学习PYTHON3讲义(二)把Python当做计算器
  17. UDP广播-缓冲区过小
  18. weka安装&配置&使用
  19. VxWorks软件开发项目实例完全解析1-VxWorks简介
  20. 两排序数组的中位数 Median of Two Sorted Arrays

热门文章

  1. CoordinatorLayout Behaviors使用说明[翻译]
  2. Parrot Linux国内源
  3. 关于Angularjs写directive指令传递参数
  4. delphi----Tstringlist,将有符号的数据变成数组"aaa,bbb,ccc"---->list[0]=aaa,list[1]=bbb
  5. sqlalchemy笔记
  6. 设计4个线程,其中2个对num进行加操作,另两个对num进行减操作
  7. 列表(List) 的增删改查及其他方法
  8. 在Mac OS X使用Elasticsearch的基本流程
  9. [动态规划]UVA437 - The Tower of Babylon
  10. Linux运维工程师:30道面试题整理