大数据(七)---------Hive详解

Hive是什么?

         hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行.

          Hive是构建在Hadoop之上的数据仓库平台,它的创造是为了让非Java程序员更方便使用MapReduce

Hive的工作原理:

接收到一个sql后:
①.词法分析/语法分析:使用antlr将SQL语句解析成抽象语法树-AST
②.语义分析:从Megastore获取模式信息,验证SQL语句中队表名,列名,以及数据类型的检查和隐式转换,以及Hive提供的函         数和用户自定义的函数(UDF/UAF)
③.逻辑计划生产:生成逻辑计划-算子树
④.逻辑计划优化:对算子树进行优化,包括列剪枝,分区剪枝,谓词下推等
⑤.物理计划生成:将逻辑计划生产包含由MapReduce任务组成的DAG的物理计划
⑥.物理计划执行:将DAG发送到Hadoop集群进行执行
⑦.将查询结果返回

Hive架构图:

 Hiveæ¶æå¾

Hive的用户接口主要有三个: CLI, Client 和 WebUI. 其中最常用的是CLI, CLI启动的时候, 会同时启动一个Hive副本; Client是Hive的客户端, 用户通过连接Hive Server (Thrift Server)连接至Hive, 在启动Client模式时, 需要指出Hive Server所在节点,并且在该节点启动Hive Server; WUI是通过浏览器访问Hive.

  Hive将元数据存储在数据库中, 如mysql、derby. Hive中的元数据包括表的名字, 表的列和分区及其属性, 表的属性(是否为外部表等), 表的数据所在目录等.

  解释器、编译器、优化器完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成. 生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行。

  Hive的数据存储在HDFS中, 大部分的查询、计算由MapReduce完成(包含*的查询,比如select * from tbl不会生成MapRedcue任务)。

 Hive中表的分类:

内部表:
    CREATE   TABLE  table_name
    删除表时,元数据与数据都会被删除
外部表:
    CREATE     EXTERNAL  TABLE    table_name
    删除外部表只删除metastore的元数据,不删除hdfs中的表数据

结构一样,但是数据不一样  ----like
            create table bws like te;

结构一样,数据也一样----as
            create table bws2 as select * from tes;

Hive添加数据的几种方式:

①将本地的数据导入到hive中:load data local inpath '/root/tes.txt' into table test.usr;

②从hdfs集群导入数据:load data  inpath 'hdfs://node01:9000/user/tes.txt' into table test.te;

③insert into---内外部表,不适应于分区

④from table1
        insert  into(overwrite) tables2             --------overwrite会覆盖该表原有的数据
            select id ,name

对数据的约束(外部文件数据的格式),在建表时加上:

ROW FORMAT DELIMITED : 行格式分隔
FIELDS TERMINATED BY ’,’ : 字段之间使用空格分隔
COLLECTION ITEMS TERMINATED BY ‘,’ : 集合(就是这的数据)使用逗号分隔
MAP KEYS TERMINATED BY ‘:’ : 键值对使用冒号分隔
LINES TERMINATED BY ‘\t’ : 记录之间使用换行符分隔

分区:

分区可以把指定范围或指定值的数据放在一起,这样更方便查询,可以减少扫描成本

1.静态分区:必须在表定义时指定对应的partition字段

①单分区建表语句:create table day_table (id int, content string) partitioned by (dt int);

   上传数据:load data local inpath '/root/tes.txt' into table test.usr partition (age=10);

②双分区建表语句:create table hour(id int, content string) partitioned by (dt int, hour int);

    先以dt为文件夹,再以hour子文件夹区分

 增加分区:alter table hour add partition(dt=10,hour=40);

 删除分区:alert table tablename drop partiton(dt=20,hour=40);  ---如果该dt分区下没有别的分区,会将dt分区也删除

2.动态分区:动态分区只有在 SQL 执行时才能决定

  修改权限的方式:①、conf/hive-site.xml
                               ②、在hive内部使用set进行相应的设置
                               ③、hive启动的时候设置 hive --hiveconf hive.exec.dynamic.partiton=true

  修改权限:set hive.exec.dynamic.partiton=true  //开启动态分区 

  修改默认状态:set hive.exec.dynamic.partition.mode=nostrict //默认strict,至少有一个静态分区 

创建分区表:
         create table psn1(
              id int,
              name string,
              likes array<String>,
              address map<string ,string>
         )
         partitioned by (age int ,sex string)
         ROW FORMAT DELIMITED 
         FIELDS TERMINATED BY ’,’ 
         COLLECTION ITEMS TERMINATED BY ‘,’ 
         MAP KEYS TERMINATED BY ‘:’ 
         LINES TERMINATED BY ‘\n’ 

写入数据:
   from psn1     //已经存在的表格并且要有数据
   insert overwrite table pas2 partiton (age,sex)
   select * distribute  by age,sex 

分桶:

对Hive(Inceptor)表分桶可以将表中记录按分桶键的哈希值分散进多个文件中,这些小文件称为桶

开启分桶:set hive.enforce.bucketing=true

创建桶:

create table psnbucket1 (
    id int,
    name string,
    age int)
    clustered by (age) into 4 buckets
    row format delimited 
    fields terminated by ','

加载数据:insert into  table psnbucket select id,name,age from psn1

抽样:select * from bucket_table tablesample(bucket 1 out of 4 on 分桶字段)

自定义函数:

自定义函数分为三种:

                         UDF:一对一          继承UDF类,重写evaluate方法

                       UDAF:多对一

                       UDTF:一对多

示例:

package com.nb.lpq;

import org.apache.hadoop.hive.ql.exec.UDF;

public class TestUdf extends UDF{
    /**
     * 把传入的参数转化为小写
     *
     */
    public String evaluate(String input){
        if(input == null)
            return null;
        return input.toLowerCase();
    }

    /*public static void main(String[] args) {
        String abc = evaluate("ABC");
        System.out.println(abc);
    }*/
}

 ②把该项目打成jar包,上传到linux集群

 ③将集群中的jar包上传到hive中:add jar /opt/software/jars/UDF.jar;

 ④创建自定义(临时)函数:create temporary function bws as  "com.hpe.TestUdf.TestUdf";      引号里是类的路径

 ⑤使用函数执行     select   bws(value)  from   test;

创建永久自定义函数:在hive-site.xml文件中添加:

<property>
    <name>hive.aux.jars.path</name>
    <value>file:///opt/module/hive/lib/app_logs_hive.jar</value>
</property>

注意:value中的值为jar包在Linux中的路径,若是多个jar包,以,(逗号)进行分割

配置成功后,直接创建函数:

create function bws as  "com.hpe.TestUdf.TestUdf"; 

使用Jdbc连接Hive: 

①在hive-site.xml文件中必须有如下配置:

<property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hivecreateDatabaseIfNotExist=true</value>
    <description>JDBC connect string for a JDBC metastore</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    <description>username to use against metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>root</value>
    <description>password to use against metastore database</description>
</property>

②在虚拟机执行命令:hiveserver2

③编写Jdbc代码

package com.nb.lpq;

import java.sql.*;

/**
 * @Author KNIGHT
 * @Date 2019/6/21 20:12
 */
public class TestJdbc {
    private static String driverName = "org.apache.hive.jdbc.HiveDriver";

    public static void main(String[] args) throws SQLException {
        try {
            //加载驱动信息
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }

        //建立连接
        Connection conn = DriverManager.getConnection("jdbc:hive2://IP地址:10000/test", "root", "root");
        Statement stmt = conn.createStatement();
        String tableName = "psn1";

//        删除表,创建表
//        stmt.execute("drop table if exists " + tableName);
//        stmt.execute("create table " + tableName + " (key int, value string)");
//        System.out.println("Create table success!");

//      展示表
        String sql = "show tables '" + tableName + "'";
        ResultSet resultSet = stmt.executeQuery(sql);
        if(resultSet.next())
            System.out.println(resultSet.getString(1));


    }

}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值