Calcite(https://calcite.apache.org/)是Apache的一个孵化器项目,它是一个构建JDBC或者ODBC访问数据库的框架,通过自定义一些adapter通过sql访问任意类型的数据,回想起我们之前使用SQL的场景只有使用访问关系数据库如MYSQL、ORACLE等,通过hive查询HDFS上的数据,但是如果我们希望通过SQL接口访问内存中的某个数据结构(首先这个结构有关系模型)、文件里面的内容(例如CSV文件、有一定结构的普通文件,其实这些可以通过hive访问)、访问hbase和一些NOSQL数据库,甚至想要跨数据源访问(hive里面的数据和mysql里面的数据进行join查询)。以上基本上代表了我们平时接触到的各种各样的数据存储的位置,而Calcite要解决的问题就是让你想办法将这些数据建立一个关系模型,然后通过SQL查询这些数据。
假设我们只使用calcite做查询,因为以上的数据基本上都是通过其他方式写入的数据,而我们需要的是通SQL查询,calcite实现了SQL语句的解析,生成物理执行计划以及查询计划的优化,用户需要向Calcite提供数据库的元数据(有哪些database(schema),每一个数据库下有哪些table,每一个表有哪些字段,每一个字段的类型是什么)和数据(每一个表中的每一行数据是什么)。除此之外,用户也可以重载它提供的执行计划,这里只是提及到了Calcite的一些基本功能,高阶功能诸如Streaming(流式查询)、Lattices(物化视图)等,目前使用Calcite的方式是作为一个本地的框架工具而非作为一个服务存在。
独立于编程语言和数据源,可以支持不同的前端和后端;
支持关系代数、可定制的逻辑规划规则和基于成本模型优化的查询引擎;
支持物化视图(materialized view)的管理(创建、丢弃、持久化和自动识别);
基于物化视图的Lattice和Tile机制,以应用于OLAP分析;
支持对流数据的查询。
假设我们只使用calcite做查询,因为以上的数据基本上都是通过其他方式写入的数据,而我们需要的是通SQL查询,calcite实现了SQL语句的解析,生成物理执行计划以及查询计划的优化,用户需要向Calcite提供数据库的元数据(有哪些database(schema),每一个数据库下有哪些table,每一个表有哪些字段,每一个字段的类型是什么)和数据(每一个表中的每一行数据是什么)。除此之外,用户也可以重载它提供的执行计划,这里只是提及到了Calcite的一些基本功能,高阶功能诸如Streaming(流式查询)、Lattices(物化视图)等,目前使用Calcite的方式是作为一个本地的框架工具而非作为一个服务存在。
Apache Calcite具有以下几个技术特性:
支持标准SQL语言;独立于编程语言和数据源,可以支持不同的前端和后端;
支持关系代数、可定制的逻辑规划规则和基于成本模型优化的查询引擎;
支持物化视图(materialized view)的管理(创建、丢弃、持久化和自动识别);
基于物化视图的Lattice和Tile机制,以应用于OLAP分析;
支持对流数据的查询。
这里有一篇介绍Calcite的文章可以参考:http://www.infoq.com/cn/articles/new-big-data-hadoop-query-engine-apache-calcite
下面主要以实践的方式介绍如何使用Calcite查询不同数据源的数据,这里我们的实验的存储是内存中的数据结构,首先我们有一个map:
public static final Map<String, Database> MAP = new HashMap<String, Database>();
public static class Database {
public List<Table> tables = new LinkedList<Table>();
}
public static class Table{
public String tableName;
public List<Column> columns = new LinkedList<Column>();
public List<List<String>> data = new LinkedList<List<String>>();
}
public static class Column{
public String name;
public String type;
}
这个MAP中存储了数据库名到我们内存中Database结构的映射,每一个Database中存储了多个Table对象,每一个Table对象有一些Column和一个二维的data数组,Column定义了字段名和类型,然后为了测试创建了一个Database对象,名为school,它包含两个Table,分别为Class和Student,Class对象的初始化如下:
cl. tableName = "Class";
Column name = new Column();
name.name = "name";
name.type = "varchar";
cl.columns.add(name);
Column id = new Column();
id.name = "id";
id.typ