Hive是基于Hadoop的数据仓库工具,提供类SQL查询功能(HQL)。
核心特点包括:
1)将HDFS文件映射为表结构;
2)使用MapReduce作为计算引擎;
3)支持PB级数据处理。
与Oracle相比,Hive查询速度较慢但支持更大数据量。
主要操作包括:数据库创建/切换、表管理(内部表与外部表区别显著)、数据加载(支持增量/全量)以及通过OVERWRITE实现更新删除。
常用语法与Oracle相似,支持JOIN、GROUP BY等操作,但UPDATE/DELETE需通过查询覆盖实现。
文件映射功能是Hive特色:通过定义表结构(含分隔符)可直接查询文本文件数据。
外部表删除时仅移除元数据,保留HDFS文件,而内部表会完全删除数据文件。
Hive 课堂笔记整理
一、Hive 概述
1.1 什么是 Hive?
| 特性 | 说明 |
|---|---|
| 定位 | 数仓管理工具(有时也被称为数据库) |
| 功能 | 提供开发环境给开发者编写 Hive SQL / HQL / HSQL |
| 基础 | 搭建在 Hadoop 集群之上 |
1.2 Hive vs Oracle 对比
| 对比项 | Oracle | Hive |
|---|---|---|
| 查询速度 | 0.001秒(快) | 30秒(慢) |
| 数据量级 | 上亿条有压力 | PB级别(1024T = 1PB) |
| 延迟原因 | 直接查询 | SQL 转换成 MR 程序运行,转换过程耗时较久 |
| 计算引擎 | 自身引擎 | MapReduce |
| 并行能力 | 有限 | 可将复杂任务拆成多个作业,分发给多个节点并行运行 |
1.3 Hive 表数据的存储方式
| 存储内容 | 存储位置 | 说明 |
|---|---|---|
| 数据文件 | HDFS | 不带表结构 |
| 元数据 | Metastore(元数据库) | 表名、列名、数据类型、分区信息、分桶信息 |
分区 与分桶在数据仓库(如 Hive)中的核心对比总结:
对比维度 分区 (Partitioning) 分桶 (Bucketing/Clustering) 核心原理 按列值创建独立的子目录(如 dt=2023-01-01)按哈希函数将数据均匀分散到固定数量的文件中 常用场景 按时间 (日期/小时)或类别进行数据隔离 数据采样 、JOIN优化 (避免全表 shuffle)、去重 粒度控制 容易产生"小文件"问题(分区过多时) 文件数量可控(由桶数决定),文件大小相对均匀 查询优化 分区裁剪:只扫描特定目录,大幅减少数据量 预聚合 + Map端 JOIN:相同桶列的两表 JOIN 更高效 定义方式 PARTITIONED BY (col_name type)CLUSTERED BY (col_name) INTO N BUCKETS数据分布 按值保存,数据可能倾斜(某分区数据量极大) 按哈希分布,数据自动均匀分散到各桶 写入管理 需手动指定分区值(动态/静态分区) 自动根据桶数写入对应文件(需开启 hive.enforce.bucketing)支持操作 可对分区进行增删改查、修复(MSCK) 分桶数量建议固定,修改代价较大 关键对比场景图示
text
文件组织方式: 分区(按日期): /data/table/dt=2023-01-01/file1.parquet /data/table/dt=2023-01-01/file2.parquet /data/table/dt=2023-01-02/file1.parquet 分桶(按用户ID哈希): /data/table/bucket_0/file.parquet (用户1,4,7...) /data/table/bucket_1/file.parquet (用户2,5,8...) /data/table/bucket_2/file.parquet (用户3,6,9...)最佳实践建议
优先使用分区 :当列是低基数 (如国家、省份)且常作为筛选条件时。
分桶作为补充 :当需要均匀抽样 、优化大表 JOIN(尤其是多表多次 JOIN)或解决数据倾斜问题时。
同时使用:可先按日期分区,再对用户 ID 进行分桶,兼顾裁剪效率与均匀分布。
1.4 核心特性
Hive 能够将文件映射成表:通过指令将文件以表的形式存储,然后通过 SQL 方式查询。
二、Hive 启动与基础操作
2.1 启动 Hive
bash
# 1. 集群离开安全模式(如果 HDFS 处于安全模式)
hadoop dfsadmin -safemode leave
# 2. 启动 Hive
hive
2.2 命令行区分
| 提示符 | 环境 | 输入内容 |
|---|---|---|
hive (default)> |
Hive 命令窗口 | Hive 指令(HQL) |
[hadoop@node100 ~]$ |
Linux 命令行 | Linux 命令 |
2.3 客户端工具
推荐客户端:DBeaver
2.4 Hive 数据文件存储目录
text
hdfs:///user/hive/warehouse
三、Hive 基础语法
3.1 数据库操作
sql
-- 查看所有数据库
show databases;
-- 创建数据库
create database 数据库名;
-- 切换数据库
use 数据库名;
3.2 数据类型
| 分类 | 类型 | 说明 |
|---|---|---|
| 数值型 | int |
整型 |
float |
浮点型 | |
double |
双精度浮点型 | |
| 字符串 | string |
字符串类型 |
| 日期型 | date / timestamp |
日期/时间戳 |
3.3 建表语法
sql
create table 表名 (
列名 数据类型,
列名 数据类型
)
row format delimited fields terminated by '分隔符';
分隔符说明:为了方便列名匹配数据文件
'\t':代表 Tab 键
'\n':换行符
3.4 建表示例
sql
-- 创建成绩表
create table t_score(
sno int,
sname string,
class string,
score float
)
row format delimited fields terminated by '-';
四、Hive 增删改查(CRUD)
4.1 增(INSERT)
sql
-- 单条插入(基本上不会用)
insert into t_score values(101, 'zhangsan', 'yuwen', 90.0);
-- 查询结果插入
insert into t_score
select * from table;
4.2 改(UPDATE)
⚠️ Hive 不支持 UPDATE 操作
4.3 删(DELETE)
| 操作 | 是否支持 | 说明 |
|---|---|---|
delete from table where ... |
❌ 不支持 | |
truncate table 表名 |
✅ 支持 | 删除 HDFS 上的数据文件,保留元数据 |
drop table 表名 |
✅ 支持 | 删除 HDFS 上的数据文件和元数据 |
4.4 查(SELECT)
sql
select * from t_score;
五、Hive 与 Oracle 的共性
5.1 基础语法
支持以下语法:
-
JOIN -
GROUP BY -
HAVING -
WHERE
5.2 函数对比
| 函数分类 | Hive | Oracle | 说明 |
|---|---|---|---|
| 数值函数 | ABS, ROUND, FLOOR, CEIL, MOD |
相同 | 用法一致 |
| 字符函数 | SUBSTRING, REPLACE, INSTR, TRIM |
相同 | 用法一致 |
| 日期函数 | CURRENT_DATE() |
SYSDATE |
获取当前日期 |
DATE_SUB / DATE_ADD |
日期 +- 数值 | 日期加减 | |
UNIX_TIMESTAMP() |
无 | 时间戳 | |
FROM_UNIXTIME() |
无 | 时间戳转日期 | |
| 聚合函数 | SUM, AVG, MIN, MAX |
相同 | 用法一致 |
| 开窗函数 | ROW_NUMBER(), LAG, LEAD, MAX OVER() |
相同 | 用法一致 |
| 转换函数 | CAST(字段 AS 数据类型) |
相同 | 用法一致 |
5.3 场景判断
| Hive | Oracle | 说明 |
|---|---|---|
CASE WHEN |
CASE WHEN |
用法一致 |
IF |
DECODE |
函数名不同 |
六、Hive 特有功能:文件映射成表
6.1 操作步骤
步骤一:构造数据文件(Linux 窗口)
bash
cd /home/hadoop/2608/test
touch emp
vim emp
# 复制 emp 表数据内容到文件中(不要带行号,不要带列名)
步骤二:在 Hive 中创建表(Hive 窗口)
sql
create table emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal float,
comm float,
deptno int
)
row format delimited fields terminated by '\t';
步骤三:导入数据文件到表(Hive 窗口)
sql
load data local inpath '/home/hadoop/2608/test/emp' into table emp;
6.2 练习
-
将
Oracle.emp导入到 Hive.数据库名.emp -
将
Oracle.dept导入到 Hive.数据库名.dept
七、Hive 实现数据更新与删除(通过 OVERWRITE)
7.1 更新操作
原理:将更新后的数据查询出来,覆盖写入到源表
sql
-- 示例:更新所有10号部门的员工薪资,上调999
insert overwrite table emp
select
empno, ename, job, mgr, hiredate,
case when deptno = 10 then sal + 999 else sal end as sal,
comm, deptno
from emp;
7.2 删除操作
原理:将删除之后的数据查询出来,然后覆盖写入
sql
-- 示例:删除所有岗位是 SALESMAN 的员工
insert overwrite table emp
select * from emp
where job <> 'SALESMAN';
7.3 加载数据方式对比
| 方式 | 语法 | 说明 |
|---|---|---|
| 增量加载 | load data local inpath '路径' into table 表; |
追加数据 |
| 全量加载 | load data local inpath '路径' overwrite into table 表; |
覆盖数据 |
7.4 练习
练习1:更新薪资
sql
-- 更新所有薪资低于2000的员工上调999,其他员工上调333
insert overwrite table emp
select
empno, ename, job, mgr, hiredate,
case when sal < 2000 then sal + 999 else sal + 333 end as sal,
comm, deptno
from emp;
练习2:删除姓名长度为4位的员工
sql
-- 删除 emp 表中所有员工姓名是4位长度的员工
insert overwrite table emp
select * from emp
where length(ename) <> 4;
八、Hive 表的类型
8.1 查看表信息
sql
-- 查看表的基本信息(列名、数据类型)
desc 表名;
-- 查看表的详细信息(包含表类型)
desc formatted 表名;
8.2 内部表 vs 外部表
| 对比项 | 内部表(MANAGED_TABLE) | 外部表(EXTERNAL_TABLE) |
|---|---|---|
| 创建方式 | 默认创建 | 需要添加 EXTERNAL 关键字 |
truncate 操作 |
✅ 允许清空 | ❌ 不允许清空 |
drop 操作 |
删除 HDFS 数据文件 + 元数据 | 只删除元数据,HDFS 数据文件保留 |
8.3 示例对比
sql
-- 清空操作
truncate table emp; -- ✅ 成功(内部表)
truncate table waibu_emp; -- ❌ 失败(外部表)
-- 删除操作
drop table emp; -- 删除数据文件 + 元数据
drop table waibu_emp; -- 只删除元数据,HDFS 数据文件保留
8.4 练习
-
分别创建内部表
t_neibu(id int)和外部表t_waibu(id int) -
在
/home/hadoop/2608/test目录下构造文件num,内容 1~10 -
将
/home/hadoop/2608/test/num文件加载到内外部表 -
依次
truncate内外部表,观察 HDFS 变化 -
依次
drop内外部表,观察 HDFS 变化
8.5 核心区别总结
| 问题 | 答案 |
|---|---|
| 默认创建什么类型的表? | 内部表 |
| 外部表如何创建? | 需要添加 EXTERNAL 关键字 |
| 外部表能否 TRUNCATE? | 不能 |
| 外部表删除后数据文件还在吗? | 在,HDFS 上的数据文件不会被删除 |
九、常用命令速查
| 命令 | 说明 |
|---|---|
show databases; |
查看所有数据库 |
create database 数据库名; |
创建数据库 |
use 数据库名; |
切换数据库 |
create table ... |
创建表 |
desc 表名; |
查看表结构 |
desc formatted 表名; |
查看表详细信息 |
load data local inpath '路径' into table 表; |
加载数据(增量) |
load data local inpath '路径' overwrite into table 表; |
加载数据(覆盖) |
insert overwrite table 表 select ... |
覆盖写入(更新/删除) |
truncate table 表名; |
清空表数据 |
drop table 表名; |
删除表 |