大数据_Hive的安装配置(远程模式)

一、Hive的安装和配置:远程模式(需要MySQL数据库)
    (*)在嵌入模式下,在哪个目录下执行的数据库初始化,就应该在哪个目录下执行: hive
    (*)远程模式:MySQL
        (1)配置MySQL的数据库:http://www.mysqlfront.de/2)配置hive-site.xml: JDBC的参数
                <?xml version="1.0" encoding="UTF-8" standalone="no"?>
                <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
                <configuration>          
                    <property>
                      <name>javax.jdo.option.ConnectionURL</name>
                      <value>jdbc:mysql://localhost:3306/hive?useSSL=false</value>
                    </property> 

                    <property>
                      <name>javax.jdo.option.ConnectionDriverName</name>
                      <value>com.mysql.jdbc.Driver</value>
                    </property> 

                    <property>
                      <name>javax.jdo.option.ConnectionUserName</name>
                      <value>hiveowner</value>
                    </property> 

                    <property>
                      <name>javax.jdo.option.ConnectionPassword</name>
                      <value>Welcome_1</value>
                    </property> 

                </configuration>
        (3)把MySQL数据库的驱动放到: Hive/lib下
        (4)初始化MySQL数据库
             老版本的Hive:第一次运行Hive
             新版本的hive:schematool -dbType mysql -initSchema


二、Hive的数据模型(重要): 表的类型 ----> 默认分隔符是:tab键
        ,MARTIN,SALESMAN,7698,1981/9/28,1250,1400,30


    1、内部表:相当于MySQL(Oracle)中表,将数据保存到Hive自己的数据仓库的目录中: /usr/hive/warehouse
            create table emp
            (empno int,
            ename string,
            job string,
            mgr int,
            hiredate string,
            sal int,
            comm int,
            deptno int
            );

            导入数据到表中:本地、HDFS
            load语句、insert语句
            load语句相当于ctrl+X

            load data inpath '/scott/emp.csv' into table emp;   ----> 导入HDFS
            load data local inpath '/root/temp/***' into table emp;   ----> 导入本地文件

            创建表,并且指定分隔符
            create table emp1
            (empno int,
            ename string,
            job string,
            mgr int,
            hiredate string,
            sal int,
            comm int,
            deptno int
            )row format delimited fields terminated by ',';

            创建部门表,保存部门数据
                create table dept
                (deptno int,
                dname string,
                loc string
                )row format delimited fields terminated by ','; 

                load data inpath '/scott/dept.csv' into table dept;


    2、分区表:提高查询的效率----> 查看SQL的执行计划
               分区 ----> 目录

        (*)根据员工的部门号建立分区
                create table emp_part
                (empno int,
                ename string,
                job string,
                mgr int,
                hiredate string,
                sal int,
                comm int
                )partitioned by (deptno int)
                row format delimited fields terminated by ',';  

                往分区表中导入数据:指明分区
                insert into table emp_part partition(deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=10;
                insert into table emp_part partition(deptno=20) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=20;
                insert into table emp_part partition(deptno=30) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=30;

        (*)Hive SQL的执行计划
        (*)补充:Oracle中的索引和执行计划
                (*)问题:索引一定可以提高查询的效率吗?
                (*)Oracle中索引两种类型:  B树索引(默认)----> 适合:insert  update delete
                                          位图索引      ----> 适合:select

oracleSQL的执行计划

索引:相当于是一本书的目录

查询10号部门的员工   select * from emp where deptno=10;

生成执行计划:
explain plan for select * from emp where deptno=10;

select * from table(dbms_xplan.display);

1、没有索引
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     3 |   261 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     3 |   261 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------


2、有索引   create index myindex on emp(deptno);
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     3 |   261 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     3 |   261 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | MYINDEX |     3 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

看索引计划,都是从上往下,从右往左。

问题: 索引一定可以提高查询的效率么
    在什么情况下,不一定会提高查询计划(数据量很少的情况下和数据严重倾斜的时候(99.9%的数据都是10号部门的员工))

    3、外部表: external table 相对于内部表
        (*)实验的数据
                [root@bigdata11 ~]# hdfs dfs -cat /students/student01.txt
                1,Tom,23
                2,Mary,24
                [root@bigdata11 ~]# hdfs dfs -cat /students/student02.txt
                3,Mike,26

        (*)定义:(1)表结构  (2)指向的路径
                create external table students_ext
                (sid int,sname string,age int)  
                row format delimited fields terminated by ','   
                location '/students';

        (*)Oracle中的外部表
            数据加载方式:
            (1)Oracle SQL*Loader 工具
            (2)Oracle的数据泵---> PLSQL程序的一个程序包

    4、桶表:本质也是一种分区表,类似Hash分区
               桶 ----> 文件
              创建一个桶表,按照员工的职位job分桶
                create table emp_bucket
                (empno int,
                ename string,
                job string,
                mgr int,
                hiredate string,
                sal int,
                comm int,
                deptno int
                )clustered by (job) into 4 buckets
                row format delimited fields terminated by ',';

                使用桶表,需要打开一个开关
                set hive.enforce.bucketing=true;

                使用子查询插入数据
                insert into emp_bucket select * from emp1;

    5、视图:view
        (*)视图是一个虚表,虚:视图是不存数据的
        (*)优点:简化复杂的查询
        (*)举例:查询部门名称、员工的姓名
                create view myview
                as
                select dept.dname,emp1.ename        
                from emp1,dept
                where emp1.deptno=dept.deptno;

                select * from myview;

        (*)补充:视图(Oracle数据库) ----> 物化视图
                  如果视图可以缓存数据,提高效率

    6、Hive的查询
        (1)查询所有的员工信息
               select * from emp1;

        (2)查询员工信息:员工号  姓名  薪水
               select empno,ename,sal from emp1;

        (3)多表查询:查询部门名称、员工的姓名
                select dept.dname,emp1.ename        
                from emp1,dept
                where emp1.deptno=dept.deptno;

        (4)子查询:hive只支持:fromwhere后面的子查询
             参考讲义的:P50

        (5)内置函数:select max(sal) from emp1;

        (6)条件函数  就是一个if else: 做一个报表:涨工资,总裁1000 经理800 其他400
select empno,ename,job,sal,
case job when 'PRESIDENT' then sal+1000
         when 'MANAGER' then sal+800
         else sal+400
end
from emp1;


select empno,ename,job,sal,
case job when 'PRESIDENT' then sal+1000
         when 'MANAGER' then sal+800
         else sal+400
end
from emp;

Oracle数据库:decode函数也是条件函数

三、Hive的Java客户端
    1、JDBC:Java的标准的访问数据库的接口
        启动Hive Server:  hiveserver2

        java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException:User: 
        root is not allowed to impersonate anonymous
        在老版本的Hive中,是没有这个问题的
        把Hadoop HDFS的访问用户(代理用户) ---> *
        core-site.xml
            <property>
               <name>hadoop.proxyuser.root.hosts</name>
               <value>*</value>
            </property>

            <property>
               <name>hadoop.proxyuser.root.groups</name>
               <value>*</value>
            </property>

    2、ODBC、Thrift Client

代码实现

package demo.jdbc;

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

//工具类:(1)获取数据库的链接  (2) 释放数据库资源: Connection, Statement, ResultSet
public class JDBCUtils {

    //Hive的驱动
    private static String driver = "org.apache.hive.jdbc.HiveDriver";
    //Oracle: oracle.jdbc.OracleDriver

    //Hive的位置
    private static String url = "jdbc:hive2://192.168.157.11:10000/default";

    //注册数据库的驱动: Java的反射
    static{
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    //获取数据库链接
    public static Connection getConnection(){
        try {
            return DriverManager.getConnection(url);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void release(Connection conn,Statement st,ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                rs = null;
            }
        }

        if(st != null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                st = null;
            }
        }

        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                conn = null;
            }
        }
    }
}
package demo.jdbc;

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

public class DemoTest {

    public static void main(String[] args) {
        String sql = "select * from emp1";

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtils.getConnection();

            //得到SQL的运行环境
            st = conn.createStatement();
            //执行SQL
            rs = st.executeQuery(sql);

            while(rs.next()){
                //姓名 薪水
                String name = rs.getString("ename");
                double sal = rs.getDouble("sal");
                System.out.println(name +"\t" + sal);
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            JDBCUtils.release(conn, st, rs);
        }

    }

}

四、Hive的自定义函数:内置函数、自定义函数(就是一个Java程序,封装我们的业务逻辑)

UDF: user define function

1、实现关系型数据库中的concat函数: 拼加字符串
      select concat('Hello  ' ,'World') from dual;  ----> Hello World

2、根据员工的薪水,判断薪水的级别
    (*) sal < 1000   ---> Grade A
    (*) 1000<= sal < 3000 ---> Grade B
    (*) sal >= 3000 ---> Grade C

3、打包
   将jar包加入hive的classpath
   add jar /root/temp/myudf.jar;

   创建别名(函数名称)
   create temporary function myconcat as 'demo.udf.MyConcatString';
   create temporary function checksal as 'demo.udf.CheckSalaryGrade';
> 代码实现
```java
package demo.udf;

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

//实现关系型数据库中的concat函数: 拼加字符串
public class MyConcatString extends UDF{

    //必须重写一个方法,方法的名字:必须叫: evaluate
    public String evaluate(String a,String b){
        return a + "*************"+b;
    }
}




<div class="se-preview-section-delimiter"></div>

“`

java中 a=null 这是什么意思
把a这个对象占用的内存资源释放掉,通过java的垃圾回收(把对象的引用指向了空值)

能不能通过java程序去干预java GC呢?
不可以,但是我们可以通过设置java虚拟机的参数,去影响java垃圾回收的机制。


```java
package demo.udf;

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

//根据员工的薪水,判断薪水的级别
public class CheckSalaryGrade extends UDF{

    public String evaluate(String salary){
        int sal = Integer.parseInt(salary);

        if(sal<1000) return "Grade A";
        else if(sal>=1000 && sal<3000) return "Grade B";
        else return "Grade C";
    }
}

java中 a=null 这是什么意思
把a这个对象占用的内存资源释放掉,通过java的垃圾回收(把对象的引用指向了空值)

能不能通过java程序去干预java GC呢?
不可以,但是我们可以通过设置java虚拟机的参数,去影响java垃圾回收的机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值