首先在Hive中创建Hbase里标。
键入>hive进入hive命令行,执行hive建表语句如下
CREATE TABLE lwb_test1(key string,xm string,nl int)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,data:xm,data:nl")
TBLPROPERTIES ("hbase.table.name" = "lwb_test1");
第一行,数创建表及属性,这个key是必须要写的,其他字段及类型加在key的后边,这里定义的是hive的字段及类型
第二行固定写法。第三行的hbase.columns.mapping是映射字段,应该是与第一行呼应的,这里定义的是hbase的字段。
第四行,hbase.table.name 是hbase的表名。
注意:这里建表叫做内部表:内部表指hive创建并通过load data inpath进数据库的表,这种表可以理解为数据和表结构都保存在一起的数据表。当你通过DROP TABLE table_name 删除元数据中表结构的同时,表中的数据也同样会从hdfs中被删除。
(意思就是删除hive表的时候,会同时删除hbase的表,毕竟是通过hive创建出来的,删除的时候删了可以理解)
第二种创建表的方法是现在HBase中创建表,这也是我现在的模式,因为hbase表是早都建好的,里边已经有业务数据了,这个时候我想用hive进行查询统计等功能,那么我需要在hive中创建与Hbase现有表对应的表,写法如下:
CREATE EXTERNAL TABLE realtimetable(key string,vin string,soc int,speed int,mileage int,cds string,vehicles_status string,savetime bigint)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,data:vin,data:soc,data:speed,data:mileage,data:cds,data:vehicles_status,:timestamp")
TBLPROPERTIES ("hbase.table.name" = "RealtimeMessage");
EXTERNAL关键字建立的就是外部表,如果Hbase已经存在了标lwb_test1,那么创建表的时候不加这个关键字会直接抛异常。
外部表指在表结构创建以前,数据已经保存在hdfs中了,通过创建表结构,将数据格式化到表的结构里。当DROP TABLE table_name 的时候,hive仅仅会删除元数据的表结构,而不会删除hdfs上的文件,所以,相比内部表,外部表可以更放心大胆的使用。(意思就是删除hive表的时候,对hbase的表不会有任何影响)
从Hbase中删除表对Hive有没有影响这个我没做实验。
注意:这里为了提高效率,通常查询是使用内部表,但是跟HBASE关联的内部表其实还是很慢的。
我的做法是直接创建一张Hive表,然后定时的将Hbase关联的表插入到纯hive表中。
做法就是
insert from table2 select * from table1;这里的table1是与hbase关联表,table2是纯hive表,没有与任何hbase关联。
为了提高table2的查询效率,这么是一个优化,那就是采用ORC格式进行存储,否则hive默认是textfile,纯文本的,我用我自己的数据实验了一下,基本ORC格式存储是textfile的 1/10,而且ORC的查询也是有优化的,从1G和10G的数据中查询效率肯定也是十分明显的。具体Hive的数据存储类型,可以自己去查。
ORC格式建表语句
CREATE TABLE lwb_test3(key string,vin string,soc int,speed int,mileage int,cds string,vehicles_status string) STORED AS ORC;
关键字:STORED AS ORC
最后是一段简单的hive程序代码,查询hbase
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
public class HiveTest1 {
/*
* 之前网上有个错误的例子,加载路径是org.apache.hadoop.hive.jdbc.HiveDriver,多了一个hadoop,应该是比较老的版本的
* 我用的hive版本是1.2.1
*/
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) {
try {
Class.forName(driverName);
Connection con = null;
con = DriverManager.getConnection("jdbc:hive2://10.10.171.169:10000", "hive", "hive");//之前是jdbc:hive:可能也是老版本的写法
Statement stmt = con.createStatement();
ResultSet res = null;
String sql = "select * from lwb_test1";
System.out.println("Running: " + sql);
res = stmt.executeQuery(sql);
System.out.println("ok");
ResultSetMetaData rsm = res.getMetaData(); // 获得列集
for (int i = 0; i < rsm.getColumnCount(); i++) {
System.out.print(rsm.getColumnName(i + 1) + "\t");
}
System.out.println();
while (res.next()) {
System.out.println(res.getString(1) + "\t" + res.getString(2) + "\t" + res.getInt(3) + "\t");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("error");
}
}
}