今天教大家借助一款框架快速实现一个数据库,这个框架就是Calcite,下面会带大家通过两个例子快速教会大家怎么实现,一个是可以通过SQL语句的方式可以直接查询文件内容,第二个是模拟Mysql查询功能,以及最后告诉大家怎么实现SQL查询Kafka数据。
CalciteCalcite是一个用于优化异构数据源的查询处理的可插拔基础框架(他是一个框架),可以将任意数据(Anydata,Anywhe)DML转换成基于SQL的DML引擎,并且我们可以选择性的使用它的部分功能。
Calcite能干什么使用SQL访问内存中某个数据使用SQL访问某个文件的数据跨数据源的数据访问、聚合、排序等(例如Mysql和Redis数据源中的数据进行join)当我们需要自建一个数据库的时候,数据可以为任何格式的,比如text、word、xml、mysql、es、csv、第三方接口数据等等,我们只有数据,我们想让这些数据支持SQL形式动态增删改查。
另外,像Hive、Drill、Flink、Phoenix和Storm等项目中,数据处理系统都是使用Calcite来做SQL解析和查询优化,当然,还有部分用来构建自己的JDBCdriver。
名词解释Token就是将标准SQL(可以理解为Mysql)关键词以及关键词之间的字符串截取出来,每一个token,会被封装为一个SqlNode,SqlNode会衍生很多子类,比如Select会被封装为SqlSelect,当前SqlNode也能反解析为SQL文本。
RelDataTypeField某个字段的名称和类型信息
RelDataType多个RelDataTypeField组成了RelDataType,可以理解为数据行
Table一个完整的表的信息
Schema所有元数据的组合,可以理解为一组Table或者库的概念
开始使用1.引入包dependencygroupIdorg.apache.calcite/groupIdartifactIdcalcite-co/artifactId!--目前最新版本-09-10日更新--version1.32.0/version/dependency
2.创建model.json文件和表结构csvmodel.json里面主要描述或者说告诉Calcite如何创建Schema,也就是告诉框架怎么创建出库。
{"version":"1.0",//忽略"defaultSchema":"CSV",//设置默认的schema"schemas":[//可定义多个schema{"name":"CSV",//相当于namespace和上面的defaultSchema的值对应"type":"custom",//写死"factory":"csv.CsvSchemaFactory",//factory的类名必须是你自己实现的factory的包的全路径"operand":{//这里可以传递自定义参数,最终会以map的形式传递给factory的operand参数"dictory":"csv"//dictory代表calcite会在sources下面的csv目录下面读取所有的csv文件,factory创建的Schema会吧这些文件全部构建成Table,可以理解为读取数据文件的根目录,当然key的名称也不一定非得用dictory,你可以随意指定}}]}
接下来还需要定义一个csv文件,用来定义表结构。
NAME:string,MONEY:stringaixiaoxian,万xiaobai,万adong,万maomao,万xixi,万zizi,万wuwu,万kuku,万
整个项目的结构大概就是这样:
3.实现Schema的工厂类在上述文件中指定的包路径下去编写CsvSchemaFactory类,实现SchemaFactory接口,并且实现里面唯一的方法cate方法,创建Schema(库)。
publicclassCsvSchemaFactoryimplementsSchemaFactory{/***pantSchema父节点,一般为root*name为model.json中定义的名字*operand为model.json中定于的数据,这里可以传递自定义参数**
parampantSchemaPantschema*paramnameNameofthisschema*paramoperandThe"operand"JSONproperty*turn*/OverridepublicSchemacate(SchemaPluspantSchema,Stringname,MapString,Objectoperand){finalStringdictory=(String)operand.get("dictory");FiledictoryFile=newFile(dictory);turnnewCsvSchema(dictoryFile,"scannable");}}4.自定义Schma类有了SchemaFactory,接下来需要自定义Schema类。
自定义的Schema需要实现Schema接口,但是直接实现要实现的方法太多,我们去实现官方的AbstractSchema类,这样就只需要实现一个方法就行(如果有其他定制化需求可以实现原生接口)。
核心的逻辑就是cateTableMap方法,用于创建出Table表。
他会扫描指定的Resource下面的所有csv文件,将每个文件映射成Table对象,最终以map形式返回,Schema接口的其他几个方法会用到这个对象。
//实现这一个方法就行了
OverrideprotectedMapString,TablegetTableMap(){if(tableMap==null){tableMap=cateTableMap();}turntableMap;}privateMapString,TablecateTableMap(){//Lookforfilesinthedictoryendingin".csv"finalSourcebaseSource=Sources.of(dictoryFile);//会自动过滤掉非指定文件后缀的文件,我这里写的csvFile[]files=dictoryFile.listFiles((dir,name)-{finalStringnameSansGz=trim(name,".gz");turnnameSansGz.endsWith(".csv");});if(files==null){System.out.println("dictory"+dictoryFile+"notfound");files=newFile[0];}//Buildamapfromtablenametotable;eachfilebe