Hive工具介绍(三)

17 篇文章 0 订阅
16 篇文章 1 订阅
Hive表的相关操作
Hive是一个数据仓库,它可以把结构化的数据文件映射为一张数据库表,并且有SQL语言的查询功能。
注意:一般来说数据仓库存放的是一些历史数据,它的作用是用来做查询分析,往往不会用来做单条记录的增加、删除、修改
Hive表的创建语法与传统的关系型数据库类似,它是它的类型会更加复杂一些,如:它的类型可以是数组、Map……
一、创建Hive表
如下我们创建一张Hive表。
表名:person
字段包含:id,name,age,fav,addr
数据类型分别为:int,String,int,String数组,Map<String,String>
 
建表语句:
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'  这个用来设定每一个字段的分隔符,这里的'\t'表示使用Tab键来进行分隔每行字段
COLLECTION ITEMS TERMINATED BY '-'  这个用来表示集合类型中每个对象的分隔符
fav ARRAY<STRING>  这个表示fav为字符串的数组类型
MAP KEYS TERMINATED BY ':'  这个用来定义MAP类型的键值对的分隔符
STORED AS TEXTFILE  这个表示使用数据文件格式,这里指的是txt类型
 
二、数据导入
在Hive中会把结构化的数据映射为一张表,上述建立的有是一个txt格式的文件,注意这个txt文件中的内容必须要按照表定义的分隔符进行分隔。
导入文件数据:
新建一个txt文件 data.txt
1    rod    18    study-game-driver    std_addr:beijing-work_addr:shanghai
2    tom    21    study-game-driver    std_addr:beijing-work_addr:beijing
3    jerry    33    study-game-driver    std_addr:beijing-work_addr:shenzhen
导入文件命令如下:
load data local inpath '/root/data.txt' overwrite into table person;
导入成功后,查询表数据:
select * from person;
 
三、表的分区与分桶
表进行分区 与分桶的目的是防止对表中数据的全量扫描,从而提升查询的性能。
删除表操作:drop table person;
  1. 表的分区(在建立表时指定分区)
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
PARTITIONED BY( dt STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
 
在上面的建表语句中,指定了以String类型的字段dt为依据进行分区,对于导入数据也存在一定的区别,在导入数据时也要指定导入哪一个分区中
load data local inpath '/root/data.txt' overwrite into table person partition(dt='20200512');
查询数据
select * from person where dt='20200512';
select addr['work_addr'] from person where dt=20200512;
 
四、表的分桶
分桶是相对于分区进行更加细粒度的划分,一旦当分区数量过于庞大时,我们就需要采用分桶来解决了。
分桶是把整个数据内容按某列属性值的Hash值进行区分
分桶应该在建立表时进行建立
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
PARTITIONED BY(dt STRING)
clustered by (id) into 3 buckets
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
上面的建表语句是分为三个桶,那如果要查找第一个桶中的所有数据查询语句如下:
select * from person tablesample(bucket 1 out of 3 on id);
 
如果运行过程中报错:is running 460233216B beyond the 'VIRTUAL' memory limit.
一般是虚拟内存设置的不对的原因
解决方案:
在hadoop的配置文件目录中,对mapred-site.xml中添加如下配置
<property>
 
    <name>mapreduce.map.memory.mb</name>
 
    <value>2048</value>
 
 </property>
 
 
  <property>
 
    <name>mapreduce.reduce.memory.mb</name>
 
    <value>2048</value>
 
 </property>
 
 
HA集群发现其中一个备NN无法启动
解决方案:
将能够启动的namenode节点的tmp/dfs/name目录下面的文件拷贝到不能启动的namenode节点上
然后重启hdfs
 
五、内部表与外部表
Hive创建的表分为内部表和外部表,对于内部表来说,在创建的时候会把数据移动到数据仓库指向的位置,如果是外部表,则仅仅记录数据所在的位置。
对于内部表,在删除的时候会把元数据和数据一起删除,外部表则仅仅只删除元数据,真正的数据不会删除。因而在共享源数据的情况下,可以选择使用外部表。
  1. 内部表
        数据文件的全部操作都是由Hive来完成的,除此外不会有其它的应用使用这个数据文件
  1. 外部表
        在实际的应用中数据文件可能不仅仅是由Hive来操作,这时一般是不可以改变数据文件的格式及位置的,这时一般是用外部表来实现Hive操作
外部表的创建方式
  1. 创建一张空表,然后导入数据
     create external table person(
     id int,
    name string,
    age int,
    fav array<string>,
    addr map<string,string>
    )
    comment 'this is a person table'
    row format delimited fields terminated by '\t'
    collection items terminated by '-'
    map keys terminated by ':'
    stored as textfile;
注意:上面的建表语句使用了external关键字
  1. 导入数据:load data local inpath '/root/data.txt' overwrite into table person;
  2. 查看数据:dfs -ls /usr/hive/warehouse/person;
            查看数据是可以看到:/usr/hive/warehouse/person/ data.txt
 
六、内置函数与自定义函数
Hive中包含了一些自定义的函数,如果内置函数不满足需求,我们也可以编写自定义函数(UDF:User Defined Function)
UDF函数有如下三种类型:
  1. UDF:用于单条数据,并且输出一个数据行,大多数函数属于这一类
  2. UDAF:可以接受多个输入,同时输出一个数据行
  3. UDTF:用于单个数据行同时产生多个输出数据行
创建一个虚拟txt文件
echo 'X' > dual.txt
创建一个虚拟表dual
create table dual (dummy string);
导入数据
load data local inpath '/root/dual.txt' overwrite into table dual;
 
拼接函数concat
select concat('a','b','c','d') from dual;
输出结果:abcd
统计记录行count
select count(1) from dual;
输出结果:1
拆分字符串并逐行输出explode、split
select explode(split('a,b,c,d,e',',')) from dual;
输出结果:
a
b
c
d
e
 
自定义函数
java代码:
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;


public class Maximum extends UDAF {
    public static class MaximumIntUDAFEvaluator implements UDAFEvaluator{


        private IntWritable result;
        @Override
        public void init() {
            result = null;
        }


        public boolean iterate(IntWritable value){
            if(value == null){
                return true;
            }
            if(result == null){
                result = new IntWritable(value.get());
            } else {
                result.set(Math.max(result.get(),value.get()));
            }
            return true;
        }


        public IntWritable terminatePartial(){
            return result;
        }


        public boolean merge(IntWritable other){
            return iterate(other);
        }


        public IntWritable terminate(){
            return result;
        }
    }
}

 

将代码打包为jar包
1.file-->Project Structure-->Artifacts
2.输入jar包的名称,Output directory的路径
3.添加好对应的包路径
4.添加对应的class文件
5.打包为jar包
上传jar包到服务器
向Hive中添加jar包
add jar /root/Maximum.jar;
使用jar包来生成一个自定义函数
create function maximumtext as 'com.xiaoxie.hive.Maximum';
测试自定义函数
select maximumtest(id) from person;
返回结果:3
 
七、通过JAVA访问Hive
 
JAVA代码与访问JDBC操作一致
import java.sql.*;


public class HiveTest {
    private static final String DRIVER = "org.apache.hive.jdbc.HiveDriver";
    private static final String DATABASE_PATH="jdbc:hive2://192.168.2.2:10000/default";
    private static final String USER_NAME="root";
    private static final String PASSWORD="123456";


    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;


        String hql = "select count(1) from person";
        int count = 0;
        try {
            //注册驱动
            Class.forName(DRIVER);
            //创建连接
            conn = DriverManager.getConnection(DATABASE_PATH,USER_NAME,PASSWORD);
            //创建statement
            stmt = conn.createStatement();
            //执行hql语句
            rs = stmt.executeQuery(hql);
            //处理结果集
            if(rs.next()){
                count = rs.getInt(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            if(rs != null)
                rs.close();
            if(stmt != null)
                stmt.close();
            if(conn != null)
                conn.close();
        }
        System.out.println(count);
    }
}

 

注意:这里需要导的包是:hive-jdbc-3.1.2.jar
 
执行时报错: Error: Could not open connection to jdbc:hive2://192.168.2.2:10000/default: java.net.ConnectException: Connection refused (Connection refused) (state=08S01,code=0)
解决方案:
1.进入到hive的配置目录conf,修改配置文件hive-site.xml
添加如下如下配置
<!--hive server2的超时时间,默认是5000-->
<property>
  <name>hive.server2.long.polling.timeout</name>
  <value>5000</value>
  <!--尤其注意时间是5000,原配置文件中会多个L,需要去掉-->
</property>
<!-- hive server2的使用端口,默认就是10000-->
<property>
  <name>hive.server2.thrift.port</name>
  <value>10000</value>
</property>
 
<!-- hive server2绑定的主机名-->
<property>
  <name>hive.server2.thrift.bind.host</name>
  <value>hadoop21</value>
</property>
2.启动hive的后台服务
hive --service hiveserver2 &
beeline
!connect jdbc:hive2://192.168.2.2:10000 root
输入上面命令后输入对应的密码
 
如果报错如下: root is not allowed to impersonate root
解决方案:
1.在hadoop的配置文件core-site.xml中添加如下属性:
<property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
</property>
<property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
</property>
2.重启hdfs
3.如果还报错,则表示hive所在的节点并不是active的节点(可以访问 http://192.168.2.2:9870/dfshealth.html),可以看到当前节点如果是 standy。需要把它所在的节点切换为active
运行java程序在linux后台可以看到执行的过程,最后执行完成后会在控制台打印出执行的结果。(注意在运行前一定要启动hive)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值