Apache Hive 学习回顾

Hive基础知识回顾

1、Hive与Hadoop的关系

        Hive是基于Hadoop的一个数据仓库工具(所以Hive的logo跟大象和黄蜂有关),可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。

        Hive使用Hadoop HDFS作为数据存储系统
        Hive使用Hadoop MapReduce来分析数据

        本质是将SQL转换为MapReduce程序。

        主要用途:用来做离线数据分析,比直接用MapReduce开发效率更高。

2、Hive与数据库的关系       

        Hive用于海量数据的离线数据分析。hive具有sql数据库的外表,但应用场景完全不同,hive只适合用来做批量数据统计分析。

  • Hive属于OLAP系统 是面向分析的 侧重于数据分析

  • 数据库属于OLTP系统 是面向事务的 侧重于数据时间交互

        更直观的对比请看下面这幅图:

 3、metadata metastore 

        Metadata即元数据。元数据包含用Hive创建的database、table、表的字段等元信息。元数据存储在关系型数据库中。

        Metastore即元数据服务,作用是:客户端连接metastore服务,metastore再去连接MySQL数据库来存取元数据。

        这样Hive就会有三种部署模式,内嵌模式、本地模式、远程模式。

        内嵌模式:使用的是内嵌的Derby数据库来存储元数据,也不需要额外起Metastore服务

        远程模式:需要单独起metastore服务,然后每个客户端都在配置文件里配置连接到该metastore服务。

        本地模式:用外部数据库来存储元数据

metadata储存位置metastore服务需不需要单独配置、启动
内嵌模式Derby

本地模式MySQL
远程模式MySQL

4、Hive的架构

        用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问Hive。

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

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

5、Hive的启动方式

        第一代客户端启动方式 /bin/hive

需要先启动metastore 服务
        前台启动命令:apache-hive-3.1.2-bin/bin/hive --service metastore

        后台启动命令:nohup apache-hive-3.1.2-bin/bin/hive --service metastore &

然后启动hive
        apache-hive-3.1.2-bin/bin/hive

        第二代客户端启动方式  bin/beeline

需要先启动metastore 
        nohup apache-hive-3.1.2-bin/bin/hive --service metastore &

启动hiveserver2:
        nohup apache-hive-3.1.2-bin/bin/hive --service hiveserver2 &

再启动beeline
        /apache-hive-3.1.2-bin/bin/beeline

最后链接hive2
        ! connect jdbc:hive2://node1:10000

Hive SQL--DDL

        数据定义语言 (Data Definition Language, DDL),是SQL语言集中对数据库内部的对象结构进行创建,删除,修改等的操作语言,这些数据库对象包括database(schema)、table、view、index等。核心语法由CREATE、ALTER与DROP三个所组成。DDL并不涉及表内部数据的操作.

1、完整建表语法树

CREATE [TEMPORARY][EXTERNAL] TABLE [IF NOT EXISTS][db_name.]table_name
[(col_name data_type [COMMENT col_comment], ... ]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)】]
[CLUSTERED BY (col_name, col_name,.….)[SORTED BY (col_name [ASC|DESC].….] 
INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED|SERDE serde_name WITH SERDEPROPERTIES (property_name=property_value..]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES(property_name=property_value,...)];
  • []中括号的语法表示可选。
  • |表示使用的时候,左右语法二选一。
  • 建表语句中的语法顺序要和上述语法规则保持一致。
  • 大写的是建表语法的关键字,用于指定某些功能。

2、建表语法解析

  • TEMPORARY

        创建一张临时表

  • EXTERNAL

        外部表(External table)中的数据不是Hive拥有或管理的,只管理表元数据的生命周期。要创建一个外部表,需要使用EXTERNAL语法关键字。

        删除外部表只会删除元数据,而不会删除实际数据。在Hive外部仍然可以访问实际数据。

        内部表(Internal table)也称为被Hive拥有和管理的托管表(Managed table)。默认情况下创建的表就是内部表,Hive拥有该表的结构和文件。换句话说,Hive完全管理表(元数据和数据)的生命周期,类似于RDBMS中的表。

        当删除内部表时,它会删除数据以及表的元数据。

        什么时候需要外部表

        当需要通过Hive完全管理控制表的整个生命周期时,请使用内部表。

        当文件已经存在或位于远程位置时,请使用外部表,因为即使删除表,文件也会被保留。

  • IF NOT EXISTS

        建表的时候,如果表名已经存在,默认会报错,通过IF NOT EXISTS关键字可以忽略异常

  • COMMENT 

        字段或列的注释是用属性COMMENT 来添加。

  • LOCATION

        在Hive建表的时候,可以通过location语法来更改数据在HDFS上的存储路径,使得建表加载数据更加灵活方便。

ROW FORMAT DELIMITED|SERDE

        其中ROW FORMAT是语法关键字,DELIMITED和SERDE二选其一。

        如果使用delimited,表示使用默认的LazySimpleSerDe类来处理数据。

        如果数据文件格式比较特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde类来处理数据,甚至支持用户自定义SerDe类。

        ROW FORMAT DELIMITED具体的子语法

[fields terminated by char]            #指定字段之间的分隔符
[collection items terminated by char]  #指定集合元素之间的分隔符
[map keys terminated by char]          #指定map类型kv之间的分隔符
[lines terminated by char]             #指定换行符
  • 默认分隔符

    • Hive在建表的时候,如果没有row format语法,则该表使用==\001默认分隔符==进行字段分割;

    • 如果此时文件中的数据字段之间的分隔符也是\001 ,那么就可以直接映射成功。

    • 针对默认分隔符,其是一个不可见分隔符,在代码层面是\001表示

    • 在vim编辑器中,连续输入ctrl+v 、ctrl+a;

    • 在实际工作中,Hive最喜欢的就是\001分隔符,在清洗数据的时候,==有意识==的把数据之间的分隔符指定为\001;

PARTITIONED BY

  • ==分区表的字段不能是表中已有的字段==;分区的字段也会显示在查询结果上;

  • 分区的字段是虚拟的字段,出现在表所有字段的后面,其值来自于加载数据到表中的时候手动指定。

  • 分区字段值的确定来自于用户价值数据手动指定(静态分区)或者根据查询结果位置自动推断(动态分区)
  • Hive支持多重分区,也就是说在分区的基础上继续分区,划分更加细粒度

分区表是一种优化表,建表的时候可以不使用,但是,当==创建分区表之后,使用分区字段查询可以减少全表扫描,提高查询的效率==。

目的为了之后的查询工作

CLUSTERED BY INTO N BUCKETS

  • 其中CLUSTERED BY (col_name)表示根据哪个字段进行分;

  • INTO N BUCKETS表示分为几桶(也就是几个部分)。

  • 需要注意,分桶的字段必须是表中已经存在的字段

使用分桶表的好处

  1. 基于分桶字段查询时,减少全表扫描
  2. JOIN时可以提高MR程序效率,减少笛卡尔积数量
  3. 分桶表数据进行抽样

STORED AS

        逻辑表中的数据,最终需要落到磁盘上,以文件的形式存储,有两种常见的存储形式。行式存储和列式存储。

  • 行式存储 -- 适合数据的插入删除
  • 列式存储 -- 适合查询
  • 行式存储textfile 文件格式 -- 不写stored by 默认使用此格式
  • ORC、Parquet 列式存储格式 -- 底层是以二进制形式存储,数据存储效率极高,方便查询,

3、数据库DDL操作

  •   ​​​​Create database

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];

-- COMMENT:数据库的注释说明语句

-- LOCATION:指定数据库在HDFS存储位置,默认/user/hive/warehouse

-- WITH DBPROPERTIES:用于指定一些数据库的属性配置。
  • desc database
-- 显示Hive中数据库的名称,其注释(如果已设置)及其在文件系统上的位置等信息。

DESCRIBE DATABASE/SCHEMA [EXTENDED] db_name;

-- EXTENDED:用于显示更多信息
  • use  database

        选择特定的数据库,切换当前会话使用哪一个数据库进行操作。

  • drop database
DROP DATABASE [IF EXISTS] database_name [RESTRICT|CASCADE];

-- 默认行为是RESTRICT,这意味着仅在数据库为空时才删除它。

-- 要删除带有表的数据库,在后面加上CASCADE
  • alter database 
--更改数据库属性
ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...);

--更改数据库所有者
ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role;

--更改数据库位置
ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path;

4、表的其他DDL操作

  • Describe table
-- 显示Hive中表的元数据信息

describe [formatted|extended] [db_name.]table_name;

-- 如果指定了EXTENDED关键字,则它将以Thrift序列化形式显示表的所有元数据。

-- 如果指定了FORMATTED关键字,则它将以表格格式显示元数据。
  • Drop table

        DROP TABLE删除该表的元数据和数据。如果已配置垃圾桶(且未指定PURGE),则该表对应的数据实际上将移动到.Trash/Current目录,而元数据完全丢失。删除EXTERNAL表时,该表中的数据不会从文件系统中删除,只删除元数据。

        如果指定了PURGE,则表数据不会进入.Trash/Current目录,跳过垃圾桶直接被删除。因此如果DROP失败,则无法挽回该表数据。

DROP TABLE [IF EXISTS] table_name [PURGE];    

         从表中删除所有行。可以简单理解为清空表的所有数据但是保留表的元数据结构。如果HDFS启用了垃圾桶,数据将被丢进垃圾桶,否则将被删除。

TRUNCATE [TABLE] table_name;
  • Alter table
--1、更改表名
ALTER TABLE table_name RENAME TO new_table_name;
--2、更改表属性
ALTER TABLE table_name SET TBLPROPERTIES (property_name = property_value, ... );
--更改表注释
ALTER TABLE student SET TBLPROPERTIES ('comment' = "new comment for student table");
--3、更改SerDe属性
ALTER TABLE table_name SET SERDE serde_class_name [WITH SERDEPROPERTIES (property_name = property_value, ... )];
ALTER TABLE table_name [PARTITION partition_spec] SET SERDEPROPERTIES serde_properties;
ALTER TABLE table_name SET SERDEPROPERTIES ('field.delim' = ',');
--移除SerDe属性
ALTER TABLE table_name [PARTITION partition_spec] UNSET SERDEPROPERTIES (property_name, ... );

--4、更改表的文件存储格式 该操作仅更改表元数据。现有数据的任何转换都必须在Hive之外进行。
ALTER TABLE table_name  SET FILEFORMAT file_format;
--5、更改表的存储位置路径
ALTER TABLE table_name SET LOCATION "new location";

--6、更改列名称/类型/位置/注释
CREATE TABLE test_change (a int, b int, c int);
// First change column a's name to a1.
ALTER TABLE test_change CHANGE a a1 INT;
// Next change column a1's name to a2, its data type to string, and put it after column b.
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
// The new table's structure is:  b int, a2 string, c int.
// Then change column c's name to c1, and put it as the first column.
ALTER TABLE test_change CHANGE c c1 INT FIRST;
// The new table's structure is:  c1 int, b int, a2 string.
// Add a comment to column a1
ALTER TABLE test_change CHANGE a1 a1 INT COMMENT 'this is column a1';

--7、添加/替换列
--使用ADD COLUMNS,可以将新列添加到现有列的末尾但在分区列之前。
--REPLACE COLUMNS 将删除所有现有列,并添加新的列集。
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type,...);

5、分区表DDL操作

  • Add partition
  • rename partition
  • delete partition
  • msck partition
  • alter partition

6、show操作

--1、显示所有数据库
show databases;
show schemas;

--2、显示当前数据库所有表
show tables;

--3、显示表分区信息,分区按字母顺序列出,不是分区表执行该语句会报错
show partitions table_name;

--4、显示表/分区的扩展信息
SHOW TABLE EXTENDED [IN|FROM database_name] LIKE table_name;
show table extended like student;

--5、显示表的创建语句
SHOW CREATE TABLE [db_name.]table_name;

--6、显示当前支持的所有自定义和内置的函数
show functions;

--7、Describe desc
-- 查看表信息
desc extended table_name;
--查看表信息(格式化美观)
desc formatted table_name;
--查看数据库相关信息
describe database database_name;

思维导图


DML(数据操纵语言)

1、load

        load加载操作是将数据文件移动到与 Hive表对应的位置的纯复制/移动操作.

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename 
[PARTITION (partcol1=val1, partcol2=val2 ...)] 
[INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)
  • 其中当中的local关键字是指从本地文件系统(hiveserver2)加载数据到Hive表中

                这个就相当于执行了hadoop fs -put 这个命令,属于复制操作

  • 如果没有local关键字是指从HDFS文件系统加载数据到Hive表中

                这个相当于执行了hadoop fs -mv 这个命令,属于移动操作,HDFS文件系统的文件将会移动到对应的HIVE表下

  • 如果使用了OVERWRITE关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。

2、insert into

  • 使用insert +value方式

        这样执行过程非常非常慢,因为Hive底层是使用MapReduce把数据写入HDFS的。

  • 使用insert + select加载数据

        在hive中,insert主要是结合 select 查询语句使用,将查询结果插入到表中

        保证后面select查询语句返回的结果字段个数、类型、顺序和待插入表一致

        如果不一致,Hive会尝试帮你转换,但是不保证成功;

  • Multi Inserts (多重插入)

        multiple inserts可以翻译成为多次插入,多重插入,核心是:一次扫描,多次插入。其功能也体现出来了就是减少扫描的次数。

        如果需要将一张表中的字段分别加载多张表中,可以使用多重插入,这样可以简化操作 

from 加载的表                     
insert overwrite table 目标表1
select 目标字段1
insert overwrite table 目标表2
select 目标字段2
...;
  • Dynamic partition inserts (动态分区插入)

        分区的值是由后续的select查询语句的结果来动态确定的,根据查询结果自动分区。

        但是需要对hive进行配置

-- 需要设置true为启用动态分区插入
set hive.exec.dynamic.partition = true

-- 设置非严格模式
set hive.exec.dtnamic.partition.mode = nonstrict

补充:对于静态分区和动态分区区别

        1、如果是在加载数据的时候人手动写死指定的  叫做静态分区 

        2、如果是通过insert+select 动态确定分区值的,叫做动态分区

         如果没有设置非严格模式,在使用动态分区时必须有一个分区进行静态加载

3、数据导出操作

--标准语法:
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
    [ROW FORMAT row_format] [STORED AS file_format] 
SELECT ... FROM ...

--Hive extension (multiple inserts):
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...

--row_format
: DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

DQL

语法树

[WITH CommonTableExpression (, CommonTableExpression)*]
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
  FROM table_reference
  [WHERE where_condition]
  [GROUP BY col_list]
  [ORDER BY col_list]
  [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list]
  ]
 [LIMIT [offset,] rows];

cluster/distribute/sort/order by

  •  order by

        ORDER BY语法类似于SQL语言中的ORDER BY语法。会对输出的结果进行全局排序,因此底层使用MapReduce引擎执行的时候,只会有一个reducetask执行。

  • distribute by

        DISTRIBUTE BY负责分,

        distribute by(字段)根据指定字段将数据分到不同的reducer,分发算法是hash散列

  • sort by 

        SORT BY负责分组内排序,

        sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。

  • cluster by

        distribute和sort的字段是同一个时,此时,cluster by = distribute by + sort by


Hive性能调优

fetch抓取机制

能不走MR就不走MR

MR本地模式

能在本地就在本地

join优化

map端jion

大表对大表jion

        空key 过滤

        空key转换

桶表join 

group by数据倾斜调优

负载均衡

task并行度(针对MR)

其他调优

执行计划explain

并行执行(没有依赖)

hive严格模式

推测执行机制

浪费资源


其他

Hive数据类型

        Hive中的数据类型指的是Hive表中的列字段类型。Hive数据类型整体分为两个类别:原生数据类型(primitive data type)和复杂数据类型(complex data type)。

        原生数据类型包括:数值类型、时间类型、字符串类型、杂项数据类型;

        复杂数据类型包括:array数组、map映射、struct结构、union联合体。

关于Hive的数据类型,需要注意:

  • 英文字母大小写不敏感;
  • 除SQL数据类型外,还支持Java数据类型,比如:string;
  • int和string是使用最多的,大多数函数都支持;
  • 复杂数据类型的使用通常需要和分隔符指定语法配合使用。
  • 如果定义的数据类型和文件不一致,hive会尝试隐式转换,但是不保证成功。
  • 可以参考LanguageManual Types - Apache Hive - Apache Software Foundation

Hive读写文件流程

        SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化。序列化是对象转化为字节码的过程;而反序列化是字节码转换为对象的过程。Hive使用SerDe(和FileFormat)读取和写入行对象。

        Hive读取文件机制:首先调用InputFormat(默认TextInputFormat),返回一条一条kv键值对记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的Deserializer,将一条记录中的value根据分隔符切分为各个字段。

       Hive写文件机制:将Row写入文件时,首先调用SerDe(默认LazySimpleSerDe)的Serializer将对象转换成字节序列,然后调用OutputFormat将数据写入HDFS文件中。

Hive的数据压缩

  • Hive的默认执行引擎是MapReduce,因此通常所说的Hive压缩指的是MapReduce的压缩。

  • 压缩是指通过==算法对数据进行重新编排==,降低存储空间。无损压缩。

  • MapReduce可以在两个阶段进行数据压缩

    • map的输出

      • 减少shuffle的数据量 提高shuffle时网络IO的效率

    • reduce的输出

      • 减少输出文件的大小  降低磁盘的存储空间

  • 压缩的弊端

    • 浪费时间

    • 消耗CPU、内存

--设置Hive的中间压缩 也就是map的输出压缩
1)开启 hive 中间传输数据压缩功能
set hive.exec.compress.intermediate=true;

2)开启 mapreduce 中 map 输出压缩功能
set mapreduce.map.output.compress=true;

3)设置 mapreduce 中 map 输出数据的压缩方式
set mapreduce.map.output.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;

--设置Hive的最终输出压缩,也就是Reduce输出压缩
1)开启 hive 最终输出数据压缩功能
set hive.exec.compress.output=true;

2)开启 mapreduce 最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;

3)设置 mapreduce 最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

4)设置 mapreduce 最终数据输出压缩为块压缩  还可以指定RECORD
set mapreduce.output.fileoutputformat.compress.type=BLOCK;  

-- 推荐使用snappy
Snappy
org.apache.hadoop.io.compress.SnappyCodec

在Hive中推荐使用ORC+snappy压缩。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值