什么是Hive
- Hive是基于Hadoop的数据仓局解决方案,用来进行数据提取、转化、加载
- 可以将结构化的数据映射为一张数据库表
- 提供类sql的查询语句HQL(Hive Query Language)
- 底层数据是存储在 HDFS 上
- Hive的本质是将 SQL 语句转换为 MapReduce 任务运行
为什么使用Hive
Hive的优点:
①提供了一个简单的优化模型
②HQL类SQL语法,简化MR开发
③支持在不同的计算框架上运行
④支持在HDFS和HBase上临时查询数据
⑤支持用户自定义函数、格式
⑥成熟的JDBC和ODBC驱动程序,用于ETL和BI
⑦稳定可靠(真实生产环境)的批处理
⑧有庞大活跃的社区
相比直接使用MapReduce,Hive直接使用相对解决了以下问题:
1、人员学习成本太高
2、项目周期要求太短
3、MapReduce实现复杂查询逻辑开发难度太大
但MapReduec和Hive都要各自优势,MapReduce执行效率更快,Hive开发效率更快。如下图所示,同样做的是wordcount,hive的代码量大大减少。
Hive的体系结构
Hive 的数据类型
- 原始类型
类型 | 示例 | 类型 | 示例 |
---|---|---|---|
TINYINT | 10Y | SMALLINT | 10S |
INT | 10 | BIGINT | 100L |
FLOAT | 3.14f | DOUBLE | 3.14 |
DECIMAL | 3.14 | BINARY | 1010 |
BOOLEAN | TRUE | STRING | 'hello’或者"hello" |
CHAR | ‘C’ | VARCHAR | 'hello’或者"hello" |
DATE | ‘2020-01-01’ | TIMESTAMP | ‘2020-01-01 00:00:00’ |
- 复杂数据类型
ARRAY:存储的数据为相同类型
MAP:具有相同类型的键值对
STRUCT:封装了一组字段
Hive元数据结构
数据结构 | 描述 | 逻辑关系 | 物理存储 |
---|---|---|---|
Database | 数据库 | 表的集合 | 文件夹 |
Table | 表 | 行数据的集合 | 文件夹 |
Partition | 分区 | 用于分割数据 | 文件夹 |
Buckets | 分桶 | 用于分布数据 | 文件 |
Row | 行 | 行记录 | 文件中的行 |
Columns | 列 | 列记录 | 每行中指定的位置 |
Views | 视图 | 逻辑概念,可跨越 多张表 | 不存储数据 |
Index | 索引 | 记录统计数据信息 | 文件夹 |
数据库(Database)
表的集合,在hdfs上表现为一个文件夹
如果没有指定数据库,则默认使用default数据库
数据表(Tables)
分为内部表和外部表
①内部表:
在HDFS中表现为所属数据库目录下的子文件夹,数据完全由Hive管理,删除表(元数据)会删除数据
②外部表(External Tables):
数据保存在指定的HDFS路径中,Hive不完全管理数据,删除表(元数据)不会删除数据
创建内部表
create table employee(
name string,
address array<string>,
personalInfo array<string>,
technol map<string,int>,
jobs map<string,string>)
// 指定分割格式
row format delimited
// 以|分割列
fields terminated by '|'
// 以,分割集合
collection items terminated by ','
// 以:分割映射
map keys terminated by ':'`在这里插入代码片`
// 以换行符"\n"分割行
lines terminated by '\n'
创建外部表
// 建表语句与mysql相似
create external table employee2(
name string,
id int,
address array<string>,
info struct<sex:string,age:int>,
technol map<string,int>,
jobs map<string,string>)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n';
// 指定存储形式及hdfs上的存储路径
store as textfile
location '/user/root/employee';
建表告高阶语句
①CTAS–as select 方式建表
通过这种方式可以将原表的结构和数据一起创建
// 创建一个ctas_employee表,数据和结构与employee相同
create table ctas_employee as select * from employee;
该种方式不能创建partition,external,bucket table
②CTE (CTAS with Common Table Expression)
// 创建表cte_employee表,表中数据及格式为r1、r3的并集
// with 表名 as (select子句),表名即为select子句的别名,表名 as (select子句)可以有多个,以逗号分隔
CREATE TABLE cte_employee AS
WITH
r1 AS (SELECT name FROM r2 WHERE name = 'Michael'),
r2 AS (SELECT name FROM employee WHERE sex_age.sex= 'Male'),
r3 AS (SELECT name FROM employee WHERE sex_age.sex= 'Female')
SELECT * FROM r1 UNION ALL SELECT * FROM r3;
③like
该种形式行复制表的结构不复制表的内容
CREATE TABLE employee_like LIKE employee;
创建临时表
临时表是应用程序自动管理在复杂查询期间生成的中间数据的方法,它只在一个session(会话)中有效,session退出后自动删除
// 方式一
create temporary table tmp_table_name1 (c1 string);
// 方式二
create temporary table tmp_table_name2 AS..
// 方式三
create temporary table tmp_table_name3 LIKE..
删除表
// 删除表
drop table table_name;
// 清空表数据
truncate table employee;
修改表
// 重命名
alter table employee rename to new_employee;
// 修正表文件格式
alter table employee set fileformat rcfile;
// 修改列名
alter table employee change old_name new_name string;
// 添加列
alter table employee add column (work string);
// 替换列
alter table employee replace columns (name string);
分区(Partitions)
分区主要用于提高性能,分区列的值将表划分为文件夹,分区列的使用方法与普通列类似,查询的时候Hive只会查询用到的分区类,会过滤掉没用到的。分区分为静态分区和动态分区
- 定义分区
create external table employee2(
name string,
id int,
phone string,
date string)
// partitioned by 定义分区
partitioned by (year int,month int)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n'
stored as textfile
location '/tmp/data/employee/';
①静态分区
// 添加静态分区
alter table employee2 ADD
patition (year=2019,month=3) partition (year=2019,month=4);
// 删除静态分区
alter table employee2 drop partition (year=2019, month=4);
②动态分区
// 使用动态分区需进行设置
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.modenonstrict;
// insert方式添加动态分区
insert into employee_partition partition(year,month) values('zhansgan',20,'22233','2017-12-16',2020,10);
分桶(Buckets)
分桶对应与HDFS中的文件,它能够提高查询处理效率
分桶只有动态分桶,定义方式如下:
create external table emp_bucket(
name string,
id int,
address array<string>,
info struct<sex:string,age:int>,
technol map<string,int>,
jobs map<string,string>)
// 通过clustered by进行分桶
clustered by(id) into 3 buckets
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n'
stored as textfile
location '/usr/test/bucket/';
set hive.enforce.bucketing=true;
插入数据
// 打开分桶
set hive.enforce.bucketing=true
// 往分桶表插入数据
insert into table emp_bucket
select * from emp_partition
注意:分桶后必须使用insert的方式加载数据
视图(Views)
- 通过隐藏子查询、连接和函数来简化查询的逻辑结构
- 虚拟表,从真实表中选取数据
- 只保存定义,不存储数据
- 如果删除或更改基础表,则查询视图将失败
- 视图是只读的,不能插入或装载数据
视图操作:create、show、drop、alter
// 创建视图
create view view_name as SELECT statement;
// 查找视图 在 hive v2.2.0之后
show tables;
// 查看视图定义
show create table view_name;
// 删除视图
drop view_name;
// 更改视图定义
alter view view_name as select statement;
侧视图(Lateral view)
- 常与表生成函数结合使用,将函数的输入和输出连接
- OUTER关键字:即使output为空也会生成结果
- 支持多层级
- 通常用于规范化行或解析JSON
创建表
样本数据
单个Lateral view
多个Lateral View
Outer 关键字
①未使用outer关键字
结果为空,什么都没有输出
②使用outer关键字