hive
------------------
   在hadoop处理结构化数据的数据仓库。
   不是:    关系数据库
         不是OLTP
         实时查询和行级更新。

hive特点
-----------------
   hive存储数据结构(schema)在数据库中,处理的数据进入hdfs.
   OLAP
   HQL / HiveQL


hive安装
-----------------
   1.下载hive2.1-tar.gz
   2.tar开
      $>tar -xzvf hive-2.1.0.tar.gz -C /soft //tar开
      $>cd /soft/hive-2.1.0              //
      $>ln -s hive-2.1.0 hive                //符号连接

   3.配置环境变量
      [/etc/profile]
      HIVE_HOME=/soft/hive
      PATH=...:$HIVE_HOME/bin

   4.验证hive安装成功
      $>hive --v

   5.配置hive,使用win7的mysql存放hive的元数据.
      a)复制mysql驱动程序到hive的lib目录下。
         ...
      b)配置hive-site.xml
         复制hive-default.xml.template为hive-site.xml
         修改连接信息为mysql链接地址,将${system:...字样替换成具体路径。
         [hive/conf/hive-site.xml]
         <property>
            <name>javax.jdo.option.ConnectionPassword</name>
            <value>root</value>
            <description>password to use against metastore database</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.ConnectionURL</name>
            <value>jdbc:mysql://192.168.231.1:3306/hive2</value>
         </property>
         <property>
            <name>javax.jdo.option.ConnectionDriverName</name>
            <value>com.mysql.jdbc.Driver</value>
            <description>Driver class name for a JDBC metastore</description>
         </property>

      6)在msyql中创建存放hive信息的数据库
         mysql>create database hive2 ;

      6)初始化hive的元数据(表结构)到mysql中。
         $>cd /soft/hive/bin
         $>schematool -dbType mysql -initSchema



hive命令行操作
------------------------
   1.创建hive的数据库

      $hive>hive --version            //
      $hive>hive --help                //

      $hive>create database mydb2 ;             //
      $hive>show databases ;
      $hive>use mydb2 ;
      $hive>create table mydb2.t(id int,name string,age int);
      $hive>drop table t ;
      $hive>drop table mydb2.t ;
      $hive>select * from mydb2.t ;     //查看指定库的表
      $hive>exit ;                  //退出

      $>hive                      //hive --service cli
      $>hive                      //hive --service cli


通过远程jdbc方式连接到hive数据仓库
--------------------------------
   1.启动hiveserver2服务器,监听端口10000
      $>hive --service hiveserver2 &

   2.通过beeline命令行连接到hiveserver2
      $>beeline                                //进入beeline命令行(于hive --service beeline)
      $beeline>!help                            //查看帮助
      $beeline>!quit                            //退出
      $beeline>!connect jdbc:hive2://localhost:10000/mydb2//连接到hibve数据
      $beeline>show databases ;
      $beeline>use mydb2 ;
      $beeline>show tables;                       //显式表


使用Hive-jdbc驱动程序采用jdbc方式访问远程数据仓库
----------------------------------------------------
   1.创建java模块
   2.引入maven
   3.添加hive-jdbc依赖
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
         <modelVersion>4.0.0</modelVersion>

         <groupId>com.it18zhang</groupId>
         <artifactId>HiveDemo</artifactId>
         <version>1.0-SNAPSHOT</version>

         <dependencies>
            <dependency>
               <groupId>org.apache.hive</groupId>
               <artifactId>hive-jdbc</artifactId>
               <version>2.1.0</version>
            </dependency>
         </dependencies>
      </project>

   4.App
      package com.it18zhang.hivedemo;

      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.Statement;

      /**
       * 使用jdbc方式连接到hive数据仓库,数据仓库需要开启hiveserver2服务。
       */
      public class App {
         public static void main(String[] args) throws  Exception {
            Class.forName("org.apache.hive.jdbc.HiveDriver");
            Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.231.201:10000/mydb2");
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("select id , name ,age from t");
            while(rs.next()){
               System.out.println(rs.getInt(1) + "," + rs.getString(2)) ;
            }
            rs.close();
            st.close();
            conn.close();
         }
      }

hive中表
-------------------
   1.managed table
      托管表。
      删除表时,数据也删除了。

   2.external table
      外部表。
      删除表时,数据不删。

hive命令
----------------
   //创建表,external 外部表
   $hive>CREATE external TABLE IF NOT EXISTS t2(id int,name string,age int)
   COMMENT 'xx' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE ;

   //查看表数据
   $hive>desc t2 ;
   $hive>desc formatted t2 ;

   //加载数据到hive表
   $hive>load data local inpath '/home/centos/customers.txt' into table t2 ;  //local上传文件
   $hive>load data inpath '/user/centos/customers.txt' [overwrite] into table t2 ;    //移动文件

   //复制表
   mysql>create table tt as select * from users ;    //携带数据和表结构
   mysql>create table tt like users ;       //不带数据,只有表结构

   hive>create table tt as select * from users ;
   hive>create table tt like users ;


   //count()查询要转成mr
   $hive>select count(*) from t2 ;
   $hive>select id,name from t2 ;


   //
   $hive>select * from t2 order by id desc ;           //MR

   //启用/禁用表
   $hive>ALTER TABLE t2 ENABLE NO_DROP;   //不允许删除
   $hive>ALTER TABLE t2 DISABLE NO_DROP;  //允许删除


   //分区表,优化手段之一,从目录的层面控制搜索数据的范围。
   //创建分区表.
   $hive>CREATE TABLE t3(id int,name string,age int) PARTITIONED BY (Year INT, Month INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

   //显式表的分区信息
   $hive>SHOW PARTITIONS t3;

   //添加分区,创建目录
   $hive>alter table t3 add partition (year=2014, month=12);

   //删除分区
   hive>ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (year=2014, month=11);

   //分区结构
   hive>/user/hive/warehouse/mydb2.db/t3/year=2014/month=11
   hive>/user/hive/warehouse/mydb2.db/t3/year=2014/month=12


   //加载数据到分区表
   hive>load data local inpath '/home/centos/customers.txt' into table t3 partition(year=2014,month=11);

   //创建桶表
   $hive>CREATE TABLE t4(id int,name string,age int) CLUSTERED BY (id) INTO 3 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

   //加载数据不会进行分桶操作
   $hive>load data local inpath '/home/centos/customers.txt' into table t4 ;

   //查询t3表数据插入到t4中。
   $hive>insert into t4 select id,name,age from t3 ;

   //桶表的数量如何设置?
   //评估数据量,保证每个桶的数据量block的2倍大小。


   //连接查询
   $hive>CREATE TABLE customers(id int,name string,age int) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;
   $hive>CREATE TABLE orders(id int,orderno string,price float,cid int) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

   //加载数据到表
   //内连接查询
   hive>select a.*,b.* from customers a , orders b where a.id = b.cid ;
   //左外
   hive>select a.*,b.* from customers a left outer join orders b on a.id = b.cid ;
   hive>select a.*,b.* from customers a right outer join orders b on a.id = b.cid ;
   hive>select a.*,b.* from customers a full outer join orders b on a.id = b.cid ;

   //explode,炸裂,表生成函数。
   //使用hive实现单词统计
   //1.建表
   $hive>CREATE TABLE doc(line string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;
   ------------------------------------------------------------------------------------------------------------------
   hive
    ------------
       $hive>CREATE TABLE t3(id int,name string,age int) PARTITIONED BY (Year INT, Month INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

    export
    ---------
       $hive>EXPORT TABLE customers TO '/user/centos/tmp.txt';       //导出表结构+数据。

       //order全排序
       $hive>select * from orders order by id asc ;

       //sort,map端排序,本地有序。
       $hive>select * from orders sort by id asc ;

       //DISTRIBUTE BY类似于mysql的group by,进行分区操作。
       //select cid , ... from orders distribute by cid sort by name ;          //注意顺序.
       $hive>select id,orderno,cid from orders distribute by cid sort by cid desc ;

       //cluster by ===>  distribute by cid sort by cid

    函数
    ----------------
       mysql>select concat('tom',1000) ;
       $hive>select current_database(),current_user() ;
       $hive>tab                       //查看帮助



    设置作业参数
    ---------------
        $hive>set hive.exec.reducers.bytes.per.reducer=xxx          //设置reducetask的字节数。
        $hive>set hive.exec.reducers.max=0                      //设置reduce task的最大任务数
        $hive>set mapreduce.job.reduces=0                   //设置reducetask个数。


    动态分区
    ---------------
       动态分区模式:strict-严格模式,插入时至少指定一个静态分区,nonstrict-非严格模式-可以不指定静态分区。
       set hive.exec.dynamic.partition.mode=nonstrict       //设置非严格模式
       $hive>INSERT OVERWRITE TABLE employees PARTITION (country, state) SELECT ..., se.cnty, se.st FROM staged_employees se WHERE se.cnty = 'US';

    159

    hive事务处理在>0.13.0之后支持行级事务。
    ---------------------------------------
       1.所有事务自动提交。
       2.只支持orc格式。
       3.使用bucket表。
       4.配置hive参数,使其支持事务。
    $hive>SET hive.support.concurrency = true;
    $hive>SET hive.enforce.bucketing = true;
    $hive>SET hive.exec.dynamic.partition.mode = nonstrict;
    $hive>SET hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
    $hive>SET hive.compactor.initiator.on = true;
    $hive>SET hive.compactor.worker.threads = 1;

       5.使用事务性操作
          $>CREATE TABLE tx(id int,name string,age int) CLUSTERED BY (id) INTO 3 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' stored as orc TBLPROPERTIES ('transactional'='true');


    聚合处理
    ---------------
       $hive>select cid,count(*) c ,max(price) from orders group by cid having c > 1 ;

    wordcount
    ----------------
       $hive>select t.word,count(*) c from ((select explode(split(line, ' ')) as word from doc) as t) group by t.word order by c desc limit 2 ;

    创建新表:stats(word string,c int) ;
       将查询结果插入到指定表中。


    view:视图,虚表
    -----------
       //创建视图
       $hive>create view v1 as select a.id aid,a.name ,b.id bid , b.order from customers a left outer join default.tt b on a.id = b.cid ;

       //查看视图
       $hive>show tables ;
       $hive>select * from v1 ;

    Map端连接
    -------------------
       $hive>set hive.auto.convert.join=true        //设置自动转换连接,默认开启了。
       //使用mapjoin连接暗示实现mapjoin
       $hive>select /*+ mapjoin(customers) */ a.*,b.* from customers a left outer join orders b on a.id = b.cid ;

    调优
    --------------------
       1.explain
          使用explain查看查询计划
          hive>explain [extended] select count(*) from customers ;
          hive>explain select t.name , count(*) from (select a.name ,b.id,b.orderno from customers a ,orders b where a.id = b.cid) t group by t.name ;

          //设置limit优化测,避免全部查询.
          hive>set hive.limit.optimize.enable=true

          //本地模式
          $hive>set mapred.job.tracker=local;          //
          $hive>set hive.exec.mode.local.auto=true   //自动本地模式,测试


          //并行执行,同时执行不存在依赖关系的阶段。??
          $hive>set hive.exec.parallel=true        //

          //严格模式,
          $hive>set hive.mapred.mode=strict        //1.分区表必须指定分区进行查询
                                           //2.order by时必须使用limit子句。
                                           //3.不允许笛卡尔积.


          //设置MR的数量
          hive> set hive.exec.reducers.bytes.per.reducer=750000000;  //设置reduce处理的字节数。

          //JVM重用
          $hive>set mapreduce.job.jvm.numtasks=1    //-1没有限制,使用大量小文件。


          //UDF
          //User define function,用户自定义函数
          //current_database(),current_user();

          //显式所有函数
          $hive>show functions;
          $hive>select array(1,2,3) ;

          //显式指定函数帮助
          $hive>desc function current_database();

          //表生成函数,多行函数。
          $hive>explode(str,exp);          //按照exp切割str.