1. 简介
1.1 定义
- Hive 由 Facebook 实现并开源,是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据映射为一张数据库表,并提供 HQL(Hive SQL)查询功能,底层数据是存储在 HDFS 上。
- 使用 Hive
- 操作接口采用类 SQL 语法,提供快速开发的能力
- 避免了去写 MapReduce,减少开发人员的学习成本
- 功能扩展很方便
1.2 Hive 架构
用户接口:包括 CLI、JDBC/ODBC、WebGUI。
元数据存储:通常是存储在关系数据库如 mysql/derby 中。
Hive 与 Hadoop 的关系
- Hive 利用 HDFS 存储数据,利用 MapReduce 查询分析数据。
- Hive是数据仓库工具,没有集群的概念,如果想提交Hive作业只需要在hadoop集群 Master节点上装Hive就可以了
3 Hive 与传统数据库异同
Hive | 关系型数据库 | |
---|---|---|
ANSI SQL | 不完全支持 | 支持 |
更新 | INSERT OVERWRITE\INTO TABLE(默认) | UPDATE\INSERT\DELETE |
事务 | 不支持(默认) | 支持 |
模式 | 读模式 | 写模式 |
查询语言 | HQL | SQL |
数据存储 | HDFS | Raw Device or Local FS |
执行 | MapReduce | Executor |
执行延迟 | 高 | 低 |
子查询 | 只能用在From子句中 | 完全支持 |
处理数据规模 | 大 | 小 |
可扩展性 | 高 | 低 |
索引 | 0.8版本后加入位图索引 | 有复杂的索引 |
4 Hive 数据模型
- Hive 中所有的数据都存储在 HDFS 中,没有专门的数据存储格式
- 在创建表时指定数据中的分隔符,Hive 就可以映射成功,解析数据。
- Hive 中包含以下数据模型:
- db:在 hdfs 中表现为 hive.metastore.warehouse.dir 目录下一个文件夹
- table:在 hdfs 中表现所属 db 目录下一个文件夹
- external table:数据存放位置可以在 HDFS 任意指定路径
- partition:在 hdfs 中表现为 table 目录下的子目录
- bucket:在 hdfs 中表现为同一个表目录下根据 hash 散列之后的多个文件
5 Hive 安装部署
Hive 安装前需要安装好 JDK 和 Hadoop。配置好环境变量。
mysql 版:
-
上传 mysql驱动到 hive安装目录的lib目录下
mysql-connector-java-5.*.jar
hive启动
/root/scripts/after_reboot.sh一键启动脚本
5 Hive 基本操作
1 Hive HQL基本操作
-
创建数据库
CREATE DATABASE test;
-
显示所有数据库
SHOW DATABASES;
-
创建表
CREATE TABLE student(classNo string, stuNo string, score int) row format delimited fields terminated by ',';
-
加载数据
load data local inpath '/root/student.txt' overwrite into table student;
这个是hive中执行的,’/root/student.txt’这个路径是在linux虚拟机中的路径
直接通过hdfs的put命令把文本文件上传到hdfs路径中 /user/hive/warehouse/test4.db/student/
登录到docker中的mysql,查看hive在mysql中的元数据
docker exec -it mysql bash
root@hadoop-master:/# mysql -uroot -p 密码是password
mysql> use hive;
mysql> show tables;
-
分组查询group by和统计 count
-
hive>select classNo,count(score) from student where score>=60 group by classNo;
2 Hive的内部表和外部表
内部表(managed table) | 外部表(external table) | ||
---|---|---|---|
概念 | 创建表时无external修饰 | 创建表时被external修饰 | |
数据管理 | 由Hive自身管理 | 由HDFS管理 | |
数据保存位置 | hive.metastore.warehouse.dir (默认:/user/hive/warehouse) | hdfs中任意位置 | |
删除时影响 | 直接删除元数据(metadata)及存储数据 | 仅会删除元数据,HDFS上的文件并不会被删除 | |
表结构修改时影响 | 修改会将修改直接同步给元数据 | 表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;) |
创建一个外部表student2
CREATE EXTERNAL TABLE student2 (classNo string, stuNo string, score int) row format
delimited fields terminated by ',' location '/root/tmp/student';
'/root/tmp/student' 是hdfs的路径
加载数据
load data local inpath '/root/tmp/student.txt' overwrite into table student2;
'/root/tmp/student.txt' 这个是虚拟机路径
显示表信息
desc formatted table_name;
删除表查看结果
drop table student;
删除数据库
drop database test4; # 数据库是空的
3 分区表
什么是分区表
- 随着表的不断增大,对于新纪录的增加,查找,删除等(DML)的维护也更加困难。
- hive中分区表实际就是对应hdfs文件系统上独立的文件夹
创建分区表
create table employee (name string,salary bigint) partitioned by (date1 string) row
format delimited fields terminated by ',' lines terminated by '\n' stored as textfile;
添加分区
alter table employee add if not exists partition(date1='2018-12-01');
加载数据到分区
load data local inpath '/root/tmp/employee.txt' into table employee partition(date1='2018-12-01');
'/root/tmp/employee.txt' 这个路径是虚拟机linux的路径
手动创建分区目录,无法识别,必须通过添加分区的命令和手动闯将的分区目录进行映射才能识别到
如果重复加载同名文件,不会报错,会自动创建一个*_copy_1.txt
动态分区
在写入数据时自动创建分区(包括目录结构)
-
导入数据
insert into table employee2 partition(date1) select name,salary,date1 from employee;
-
使用动态分区需要设置参数
set hive.exec.dynamic.partition.mode=nonstrict;
6 Hive 函数
1 内置函数
- 简单函数: 日期函数 字符串函数 类型转换
- 统计函数:sum avg distinct
- 集合函数:size array_contains
- show functions 显示所有函数;
- desc function 函数名;
- desc function extended 函数名;
2 Hive 自定义函数
- UDF: 用户自定义函数(user-defined function)
- UDAF: 用户自定义聚合函数 (user-defined aggregation function)
- UDF相当于mapper UDAF相当于reducer
java版
hadoop fs -mkdir /user/hive/lib
hadoop fs -put hive-contrib-2.3.4.jar /user/hive/lib/
hive> add jar hdfs:///user/hive/lib/hive-contrib-2.3.4.jar ;
hive> CREATE TEMPORARY FUNCTION row_sequence as 'org.apache.hadoop.hive.contrib.udf.UDFRowSequence'
或者是非临时函数
CREATE FUNCTION row_sequence as 'org.apache.hadoop.hive.contrib.udf.UDFRowSequence'
using jar 'hdfs:///user/hive/lib/hive-contrib-2.3.4.jar';
Select row_sequence(),* from employee;
python
编写map风格脚本
加载文件到hdfs
hadoop fs -put udf.py /user/hive/lib/
ADD FILE hdfs:///user/hive/lib/udf.py;
Transform
SELECT TRANSFORM(fname, lname) USING 'python udf.py' AS (fname, l_name) FROM u2;