当前位置:   article > 正文

大数据 -- 04-- Hive_hive 表结构变更replace影响元数据吗

hive 表结构变更replace影响元数据吗

Hive

在这里插入图片描述

Hadoop在分布式数据处理中遇到的问题

  1. MR开发调试复杂,不适合要求快速得出结果的场景。
  2. Hadoop由Java开发,对JAVA支持最好,对其他语言的使用者不够友好。
  3. 需要对Hadoop底层具有一定的了解,并且熟悉API才能开发出优秀的MR程序。

概述

Hive是一个建立在Hadoop基础之上的数据仓库工具,以HiveQL(类SQL)的操作方式让我们能够轻松的实现分布式的海量离线数据处理。而不必去编写调试繁琐的MR程序。
在这里插入图片描述
在这里插入图片描述

优点:

  1. 避免了MR繁琐的开发调试过程,Hive自动将我们输入的HQL编译为MR运行
  2. HQL这种类SQL语言对于任何开发语言的程序员来说都比较友好。
  3. 我们不需要对Hadoop底层有太多的理解,也不用记忆大量的API就能实现分布式数据的处理
  4. Hive也提供了自定义函数的方式来补充自身函数库可能存在的不足。即编写JAVA代码来实现复杂的逻辑并封装为UDF(自定义函数)来供我们重复使用。

数据仓库

数据仓库是一个面向主题的,稳定的,集成的,反应历史数据的数据存储工具,他主要支持管理者的决策分析。

在这里插入图片描述

安装

Hive安装非常简单,解压之后即可直接运行,不需要太多配置,前提是要配置JAVA_HOME和HADOOP_HOME。并且Hadoop要全量启动(五个进程)

在这里插入图片描述

初始化元数据库

schematool -dbType derby -initSchema
  • 1

启动

在/home/app/apache-hive-2.3.6-bin/bin目录下执行

./hive
  • 1

基础操作

  • 创建数据库
create database jtdb;
  • 1

在这里插入图片描述
结论1:Hive中的数据库,其实就是HDFS中/user/hive/warehouse目录下的以.db结尾的文件夹。

  • 创建表
create table tb_user(id int,name string);
  • 1

在这里插入图片描述
结论2:Hive中的表其实就是HDFS中对应数据库文件夹下的一级文件夹。

  • 插入数据
insert into table tb_user values(1,"dongcc");
  • 1

在这里插入图片描述
结论3:Hive在必要的时候会将HQL编译为MR来执行,上图展示了变异后的MR执行的过程。

在这里插入图片描述
结论4:hive中的数据在HDFS中以文件的形式存储在其所在表的文件夹中。
在这里插入图片描述
结论5:默认数据库default没有自己单独的文件夹,其下的表直接存放在/user/hive/warehouse下。

  • 加载数据
Load data local inpath '/home/data/book1.txt' into table table_name;
  • 1

其中,local关键字为标识从本地文件系统中读取文件,如果不加,默认从HDFS中读取指定文件。

元数据库的替换

Hive没有将描述数据库、表、数据之间关系的元数据直接存放在HDFS中,而是存放在了传统的关系型数据库中,这样保证了元数据可以快速的进行增删改查。

Hive原生的将元数据保存在了内置的Derby数据库中。

Derby存在的问题:过于轻量级,性能较低,安全性不高,不适合生产。

这种情况我们是无法忍受的,实际开发中不会使用Derby来做Hive的元数据库。所以我们要将他替换掉。以mysql为例。

修改配置文件hive-site.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
 
<configuration>
 
  <property>
 
  <name>hive.default.fileformat</name>
 
  <value>TextFile</value>
 
</property>
 
<property>
 
  <!--端口改为你自己的端口,这里是连接数据库中hive数据库-->
 
  <name>javax.jdo.option.ConnectionURL</name>
 
  <value>jdbc:mysql://hadoop01:3306/hive?createDatabaseIfNotExist=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>
 
  <!--连接MySQL的用户名-->
 
  <name>javax.jdo.option.ConnectionUserName</name>
 
  <value>root</value>
 
  <description>username to use against metastore database</description>
 
</property>
 
<property>
 
  <!--连接MySQL的密码-->
 
  <name>javax.jdo.option.ConnectionPassword</name>
 
  <value>root</value>
 
  <description>password to use against metastore database</description>
 
</property>
 
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

导入驱动包

直接将mysql驱动包上传到hive的lib目录中即可

/home/app/apache-hive-2.3.6-bin/lib

开放mysql权限

进入mysql客户端(命令行)执行

grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
 
flush privileges;    
  • 1
  • 2
  • 3

初始化

schematool -dbType mysql -initSchema
  • 1

元数据信息

在这里插入图片描述

  • DBS:数据库信息
    在这里插入图片描述
  • TBLS:表信息
    在这里插入图片描述
  • SDS:表详细信息
    在这里插入图片描述
  • COLUMNS_V2:列信息
    在这里插入图片描述

表的分类

内部表和外部表

内部表(托管表):MANAGED_TABLE

  • Hive中先创建表后插入或上传数据的表称之为内部表。

创建语句:

create table table_name (id int,name string) row format delimited fields terminated by '\t';
  • 1

加载数据:

load data local inpath '文件路径' into table table_name;
  • 1

删除表:

drop table table_name;
  • 1

删除表时,连同数据一起被删除。

再次加载数据一样可以被管理到。

外部表:EXTERNAL_TABLE

Hive中先有数据后创建表来管理数据的表叫做外部表。

创建表:在创建之前先要有数据。

create external table table_name (id int ,name string) row format delimited fields terminated by '\t' location 'HDFS中文件所在路径';
  • 1

删除表:

drop table table_name;
  • 1

外部表在删除时,只会将元数据信息删掉,而不会删除数据本身。

再次加载数据一样可以被管理。

内外部表的区别

  • 内部表在被drop的时候,元数据信息会被删除,表数据也会被删除。
  • 外部表在被drop的时候,元数据信息会被删除,表数据不会被删除

分区表

在hive中数据的面向主题存储就是由表的分区来实现的。

单级分区

  • 创建分区表:
create table table_name (id int,name string) partitioned by (country string) row format delimited fields terminated by '\t';
  • 1

与普通表相比只是多了partitioned by (country string)

  • 为分区表中载入数据:
load data local inpath '文件位置' overwrite into table table_name partition (country='CHN');
  • 1

在这里插入图片描述
经过查看HDFS中存储发现:

分区在表所在目录中以文件夹形式存在,数据落在分区目录中,并且分区文件夹以分区类型=分区名定义如上图country=CHN;

另外在select * from tb_par;时发现:

在这里插入图片描述
分区信息查询结果中展示多出了一列,这并不是给数据增加了一个字段。而是单独的分区信息绑定,当然你可以把它当做一个字段来使用,比如作为条件查询。

多级分区

在这里插入图片描述
在这里插入图片描述

创建多级分区表:

create table table_name (id int,name string) partitioned by (country string, gender string) row format delimited fields terminated by '\t';
  • 1

加载数据:

load data local inpath '/home/data/JPA_female.txt' overwrite into table tb_par2 partition (country='JPA',gender='female');
  • 1

查看元数据:发现分区就是多了几级目录。
在这里插入图片描述
查询多级分区目录:

select * from tb_par2 where gender = 'female' and country = 'JPA';
  • 1

注意:在实际的生产中分区不是随意设置的,也不是越多越好,而是将经常查询的维度设置为分区即可!

分桶表

在测试过程中,每次都将全表数据加载进来会花费非常多的时间,而随意截取部分数据进行测试又不具有代表性,这时我们可以使用分桶的方法,来减少测试数据量,并使结果具有较高的代表性。

在这里插入图片描述
创建测试数据表:

create table tb_data (id int,name string) row format delimited fields terminated by ',';
  • 1

加载数据:

load data local inpath '/home/data/teachers.txt' into table tb_data;
  • 1

在这里插入图片描述
创建分桶表:

create table table_name (id int,name string) clustered by (id) into 4 buckets row format delimited fields terminated by ',';
  • 1

开启分桶模式:

Hive默认未开启多个reduce,分桶需要多个reduce同时工作,所以这里要开启分桶模式:

set hive.enforce.bucketing=true;
  • 1

然后进行导入:这个过程时间较长,桶越多时间越长。

insert into table table_name select * from tb_data;
  • 1

在这里插入图片描述
在这里插入图片描述
数据顺序发生了改变,查看HDFS存储发现整个文件被拆分成四部分,自动命名0~3;

数据取样

select * from table_name tablesample (bucket x out of y on id);
  • 1

其中x为第几个桶,不能大于总桶数, y为选取数据的步长(几个桶取一次数据)。Y应为桶数的因数或倍数,当y大于桶数时,选取结果非整桶抽取,而是抽取每桶中的y除以桶数分之一,即:1/(y/桶数)

按百分比取样:整表数据额百分之三十

select * from table_name tablesample(30 percent);
  • 1

进阶:hivejdbc

在Hadoop配置文件中加入以下内容

hdfs-site.xml

<property>  
<name>dfs.webhdfs.enabled</name>  
<value>true</value>  
</property>  
  • 1
  • 2
  • 3
  • 4

core-site.xml

<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

启动hiveserver2

在hive安装目录下的bin目录中执行

./hiveserver2
  • 1

pom

<?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>cn.tedu</groupId>
    <artifactId>flume</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>2.3.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
 
    </dependencies>
</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

代码

package cn.tedu.flume;
 
import java.sql.*;
 
public class HiveJDBC {
    private static String driverName = "org.apache.hive.jdbc.HiveDriver";
 
    /**
     * @param args
     * @throws SQLException
     */
    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.exit(1);
        }
        Connection con = DriverManager.getConnection("jdbc:hive2://hadoop01:10000/default", "root", "");
        Statement stmt = con.createStatement();
        String dbName = "test";
        String tableName = dbName+".tb_test";
        System.out.println("insert into table "+ tableName + " values(1, 'dongcc')");
        stmt.execute("drop database if exists " + dbName);
        stmt.execute("create database " + dbName);
        stmt.execute("drop table if exists " + tableName);
        stmt.execute("create table " + tableName + " (key int, value string)");
        stmt.execute("insert into table " + tableName + " values(1, 'dongcc')");
        // show tables
        String sql = "select * from "+tableName;
        System.out.println("Running: " + sql);
        ResultSet res = stmt.executeQuery(sql);
        if (res.next()) {
            System.out.println(res.getString(1));
            System.out.println(res.getString(2));
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

补充

数据仓库和关系型数据库的区别:
在这里插入图片描述

所有的离线数据处理场景都适用hive吗?

并不是所有场景都适合,逻辑简单又要求快速出结果的场景Hive优势更大。但是在业务逻辑非常复杂的情况下还是需要开发MapReduce程序更加直接有效。

Hive能作为业务系统的数据库使用吗?

不能。传统数据库要求能够为系统提供实时的增删改查,而Hive不支持行级别的增删改,查询的速度也不比传统关系型数据库,而是胜在吞吐量高,所以不能作为关系型数据库来使用。

Hive与传统MR方式处理数据相比能够提高运行效率吗?能够提高工作效率吗?

Hive的使用中需要将HQL编译为MR来运行,所以在执行效率上要低于直接运行MR程序。但是对于我们来说,由于只需要编写调试HQL,而不用开发调试复杂的MR程序,所以工作效率能够大大提高。

Hive为什么不支持行级别的增删

Hive不支持行级别的增删改的根本原因在于他的底层HDFS本身不支持。在HDFS中如果对整个文件的某一段或某一行内容进行增删改,势必会影响整个文件在集群中的存放布局。需要对整个集群中的数据进行汇总,重新切块,重新发送数据到每个节点,并备份,这样的情况是得不偿失的。所以HDFS的设计模式使他天生不适合做这个事

HDFS只提供追加写的API. 如果非要跟新,HDFS就得先把整个文件全部下载下来,修改完了,再重新覆盖上传 ,效率极低.

知识回顾

Hive是什么? 是一个基于Hadoop的数据仓库客户端,使用SQL的方式操作.内置了非常丰富的函数库.并且支持自定义函数.
数据仓库? 一个面向主题的,稳定的,集成的,反应历史数据的数据存储系统,一般为管理者提供决策分析的数据支持.
内部表: 先创建表然后在表中写数据
外部表: 托管表:先有数据,然后根据数据文件的格式,创建表结构,然后将表结构映射在数据上
内部表删除数据时,元数据和表数据都会被删除,外部表删除时,元数据会被删除,表数据则不会被删除
分区表:Hive作为数据仓库实现面向主题的唯一方式.
分桶表:只在测试阶段使用,为了解决,数量大,并且数据依据时间或者类似其他维度有规律.测试时如果全量原始数据加载测试,耗时太长,如果随意抽取部分数据结果不具有代表性,可能会影响判断. 此时,使用分桶表来解决这个数据抽样问题

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/977045
推荐阅读
相关标签
  

闽ICP备14008679号