一、引言
在上一篇博客中,我们学习了Hadoop的三大核心组件:HDFS、MapReduce和YARN。HDFS解决了数据存不下的问题,MapReduce解决了数据算不动的问题。
但还有一个问题没有解决:MapReduce的编程门槛太高了。
Hive 正是为了解决这个问题而生的。它让我们可以用SQL的方式操作Hadoop上的大数据,将SQL自动翻译成MapReduce任务。这大大降低了大数据分析的门槛。
本篇博客将系统讲解Hive的架构原理、安装搭建、DDL(数据定义语言)和DML(数据操作语言),带你从零开始掌握Hive。
二、Hive架构原理
2.1 Hive是什么
Hive 是一个基于Hadoop的数据仓库工具,它提供了类SQL的查询语言(HQL),可以将SQL语句自动翻译成MapReduce任务执行。
核心价值:
-
降低门槛:会SQL就能分析大数据
-
生态融合:与HDFS、MapReduce、YARN无缝集成
-
扩展性强:支持自定义函数(UDF)、自定义存储格式
Hive的本质 :一个SQL到MapReduce的翻译器。
2.2 Hive架构详解
Hive由以下核心组件构成:
| 组件 | 作用 | 说明 |
|---|---|---|
| 用户接口(Client) | 用户访问入口 | CLI、JDBC/ODBC |
| 元数据(Metastore) | 存储元数据 | 默认Derby,推荐MySQL |
| 驱动器(Driver) | SQL处理引擎 | 解析、优化、生成计划 |
| Hadoop | 底层执行引擎 | HDFS + MapReduce + YARN |
2.3 用户接口(Client)
Hive提供了多种用户访问方式:
| 接口 | 说明 | 适用场景 |
|---|---|---|
| CLI | 命令行界面 | 交互式查询、脚本执行 |
| JDBC/ODBC | 编程接口 | 应用程序连接 |
| HiveServer2 | 服务端 | 远程连接Hive |
CLI 是最常用的方式,直接在终端输入hive命令即可进入Hive交互界面。
2.4 元数据(Metastore)
元数据(Metastore) 是Hive的核心组件,存储了Hive表的定义信息。
元数据包括:
-
数据库 :默认数据库
default -
表名:表的名称
-
表的拥有者:创建表的用户
-
列/分区字段:表的列定义和分区信息
-
表的类型:内部表还是外部表
-
表的数据所在目录:HDFS上的存储路径
元数据存储方式:
| 存储方式 | 说明 | 适用场景 |
|---|---|---|
| Derby | Hive自带的嵌入式数据库 | 单用户测试 |
| MySQL | 独立的关系型数据库 | 生产环境,多人开发 |
为什么推荐MySQL?
-
Derby只支持单客户端访问,多人同时访问会冲突
-
MySQL支持并发访问,适合生产环境
-
便于备份和迁移
2.5 驱动器(Driver)
驱动器(Driver) 是Hive的大脑,负责将SQL语句翻译成MapReduce任务。它的工作流程如下:
步骤1:解析器(SQL Parser)
将SQL字符串转换成抽象语法树(AST)。
步骤2:语义分析器(Semantic Analyzer)
将AST进一步划分为QueryBlock(查询块),验证表和列的合法性。
步骤3:逻辑计划生成器(Logical Plan Generator)
将语法树生成逻辑计划,描述要做什么。
步骤4:逻辑优化器(Logical Optimizer)
对逻辑计划进行优化,如谓词下推、列裁剪等。
步骤5:物理计划生成器(Physical Plan Generator)
根据优化后的逻辑计划生成物理计划,描述怎么做。
步骤6:物理优化器(Physical Optimizer)
对物理计划进行优化,如选择Map Join还是Reduce Join。
步骤7:执行器(Executor)
执行该计划,得到查询结果并返回给客户端。
2.6 SQL到MapReduce的转换示例
以
sql
select
clazz,
count(1)
from
students
group by
clazz;
为例:
抽象语法树(AST) :
sql
TOK_QUERY
├── from
│ └── TOK_DESTINATION
│ └── TOK_DIR
│ └── TOK_TMP_FILE
└── TOK_INSERT
├── select
├── group by
└── ...
逻辑计划:
sql
Table Scan → Select → group by
物理计划:
sql
Map Tree:
Table Scan → Select → group by
Reduce Tree:
Table Scan → Select → group by
执行过程:
-
Map阶段 :读取students表,输出
(clazz, 1)的键值对 -
Shuffle阶段:将相同clazz的键值对发送到同一个Reduce
-
Reduce阶段 :对每个clazz的value求和,输出
(clazz, count)
三、Hive安装搭建
3.1 安装步骤
步骤1:上传解压并配置环境变量
bash
# 上传解压
tar -xvf hive-3.1.3.tar.gz
# 配置环境变量
vim /etc/profile
export HIVE_HOME=/usr/local/soft/hive-3.1.3
export PATH=$PATH:$HIVE_HOME/bin
source /etc/profile
步骤2:修改配置文件
bash
cd /usr/local/soft/hive-3.1.3/conf
vim hive-site.xml
步骤3:初始化Hive
bash
schematool -dbType mysql -initSchema
步骤4:启动Hive(需先启动Hadoop)
bash
# 启动Hive元数据服务(必须启动)
nohup hive --service metastore >> metastore.log 2>&1 &
# 启动HiveServer2服务(远程连接时启动)
nohup hive --service hiveserver2 >> hiveserver2.log 2>&1 &
# 启动Hive客户端
hive
3.2 常见配置
XML
<property>
<name>hive.cli.print.header</name>
<value>true</value>
<description>显示列名</description>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
<description>显示当前数据库</description>
</property>
四、DDL数据定义语言
4.1 数据库操作
创建数据库:
sql
-- 创建数据库,不指定路径
CREATE DATABASE db_test1;
-- 创建数据库,指定路径
CREATE DATABASE db_test2 LOCATION '/db_test2';
-- 创建数据库,带有dbproperties
CREATE DATABASE db_test3 WITH DBPROPERTIES('create_date'='2025-08-26');
-- 创建数据库,带有注释
CREATE DATABASE db_test4 COMMENT '测试库';
查询数据库:
sql
-- 查询所有数据库
SHOW DATABASES;
-- 查询匹配的数据库
SHOW DATABASES LIKE 'db_test*';
-- 查询数据库基本信息
DESC DATABASE db_test3;
-- 查看数据库更多信息
DESC DATABASE EXTENDED db_test3;
修改数据库:
sql
-- 修改dbproperties
ALTER DATABASE db_test3 SET DBPROPERTIES('create_date'='2025-08-27');
-- 修改location
ALTER DATABASE db_test1 SET LOCATION 'hdfs://master:9000/db_test1';
删除数据库:
sql
-- 删除空数据库
DROP DATABASE db_test2;
-- 删除非空数据库(级联删除)
DROP DATABASE db_test1 CASCADE;
-- 安全删除
DROP DATABASE IF EXISTS db_test2;
切换数据库:
sql
USE db_test3;
4.2 表操作
创建表
完整语法:
sql
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 row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
关键概念:
| 关键字 | 含义 | 说明 |
|---|---|---|
TEMPORARY |
临时表 | 会话结束自动删除 |
EXTERNAL |
外部表 | Hive只管理元数据,不管理数据 |
PARTITIONED BY |
分区表 | 按字段分区存储 |
CLUSTERED BY |
分桶表 | 按字段哈希分桶 |
ROW FORMAT |
行格式 | 指定分隔符 |
STORED AS |
存储格式 | TEXTFILE、ORC、PARQUET |
LOCATION |
存储路径 | HDFS路径 |
内部表 vs 外部表:
| 对比项 | 内部表 | 外部表 |
|---|---|---|
| 数据管理 | Hive完全管理 | Hive只管理元数据 |
| 删除表 | 元数据+数据都删除 | 只删除元数据 |
| 适用场景 | 中间表、临时表 | 原始数据、共享数据 |
创建表示例:
sql
-- 内部表
CREATE TABLE students(
id STRING COMMENT '学号',
name STRING COMMENT '姓名',
age INT COMMENT '年龄',
sex STRING COMMENT '性别',
clazz STRING COMMENT '班级'
);
-- 外部表
CREATE EXTERNAL TABLE students2(
id STRING COMMENT '学号',
name STRING COMMENT '姓名',
age INT COMMENT '年龄',
sex STRING COMMENT '性别',
clazz STRING COMMENT '班级'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
-- CTAS(Create Table As Select)
CREATE TABLE student3 AS SELECT * FROM students2;
-- Create Table Like
CREATE TABLE student5 LIKE students2;
查看表
sql
-- 展示所有表
SHOW TABLES;
-- 查看stu开头的表
SHOW TABLES LIKE 'stu*';
-- 查看表基本信息
DESC students;
-- 查看表详细信息
DESC FORMATTED students;
修改表
sql
-- 重命名表
ALTER TABLE students RENAME TO students7;
-- 新增列
ALTER TABLE students7 ADD COLUMNS(score FLOAT COMMENT '成绩');
-- 修改列(改名+改类型)
ALTER TABLE students7 CHANGE COLUMN sex gender STRING;
-- 替换列
ALTER TABLE students7 REPLACE COLUMNS(id STRING, name STRING);
删除表
sql
-- 删除内部表(元数据+数据)
DROP TABLE students7;
-- 删除外部表(只删元数据)
DROP TABLE students2;
清空表
sql
-- 清空内部表
TRUNCATE TABLE student3;
注意 :TRUNCATE只能清空内部表,不能清空外部表。
五、DML数据操作
5.1 Load加载数据
语法:
sql
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE]
INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];
示例:
sql
-- 加载本地文件
LOAD DATA LOCAL INPATH '/root/student.csv' OVERWRITE INTO TABLE student5;
-- 加载HDFS文件
LOAD DATA INPATH '/student2/student.csv' OVERWRITE INTO TABLE student6;
注意:
-
LOCAL:从本地文件系统加载 -
不带
LOCAL:从HDFS加载,相当于mv操作 -
OVERWRITE:覆盖原有数据
5.2 Insert插入数据
方式一:将查询结果插入表中
sql
INSERT OVERWRITE TABLE student7 SELECT * FROM student6;
方式二:插入Values
sql
INSERT INTO student7 VALUES('1500100011','张三',25,'女','文科六班');
方式三:将查询结果写入目标路径
sql
INSERT OVERWRITE LOCAL DIRECTORY '/root/student7'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT * FROM student7;
5.3 Export & Import
导出:
sql
EXPORT TABLE student7 TO '/student7';
导入:
sql
IMPORT TABLE student8 FROM '/student7';
六、实战案例
6.1 学生表统计
sql
-- 创建学生表
CREATE TABLE students(
id STRING,
name STRING,
age STRING,
gender STRING,
clazz STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/data/students';
-- 上传数据
-- hdfs dfs -put students.csv /data/students
-- 统计每个班级的人数
SELECT clazz, COUNT(1) FROM students GROUP BY clazz;
6.2 车流量统计
sql
-- 创建车流量表
CREATE TABLE gateway_records2(
plate_number STRING COMMENT '车牌号',
gateway_id STRING COMMENT '卡口编号',
city STRING COMMENT '卡口所在城市',
car_brand STRING COMMENT '车辆品牌',
road_id STRING COMMENT '道路编号',
speed DOUBLE COMMENT '车辆速度',
travel_direction STRING COMMENT '车辆行驶方向'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/data/records';
-- 统计每个城市的车流量
SELECT city, COUNT(1) AS num FROM gateway_records GROUP BY city;
6.3 成绩统计
sql
-- 创建成绩表
CREATE TABLE scores(
id STRING,
cid STRING,
score DOUBLE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/data/scores';
-- 计算每个学生的总分
SELECT id, SUM(score) AS sum_score FROM scores GROUP BY id;
七、常见问题与解决
7.1 中文乱码问题
问题:Hive表中的中文注释显示乱码。
解决方案:修改MySQL中的Hive元数据表字符集。
sql
mysql -uroot -p123456
USE hive;
-- 修改表字段的注解
ALTER TABLE hive.COLUMNS_V2 MODIFY COLUMN COMMENT VARCHAR(256) CHARACTER SET utf8;
-- 修改表的注解
ALTER TABLE hive.TABLE_PARAMS MODIFY COLUMN PARAM_VALUE VARCHAR(4000) CHARACTER SET utf8;
-- 修改分区注解
ALTER TABLE hive.PARTITION_PARAMS MODIFY COLUMN PARAM_VALUE VARCHAR(4000) CHARACTER SET utf8;
ALTER TABLE hive.PARTITION_KEYS MODIFY COLUMN PKEY_COMMENT VARCHAR(4000) CHARACTER SET utf8;
-- 修改数据库注解
ALTER TABLE hive.DBS MODIFY COLUMN `DESC` VARCHAR(4000) CHARACTER SET utf8;
-- 重启MySQL
systemctl restart mysqld
注意:以上修改只对新建的表生效,以前建的表不会生效。
7.2 元数据服务启动失败
问题 :hive --service metastore启动失败。
解决方案:
-
检查MySQL是否启动
-
检查
hive-site.xml中的MySQL连接配置 -
查看日志文件
metastore.log
八、总结
本篇博客系统讲解了Hive的架构原理、安装搭建、DDL和DML操作:
| 知识点 | 核心内容 |
|---|---|
| Hive架构 | Client、Metastore、Driver、Hadoop |
| 元数据 | 存储表定义,推荐MySQL |
| 驱动器 | 解析→语义分析→逻辑计划→物理计划→执行 |
| 数据库操作 | CREATE、SHOW、DESC、ALTER、DROP |
| 表操作 | 内部表、外部表、分区表、分桶表 |
| DML操作 | LOAD、INSERT、EXPORT/IMPORT |
核心要点:
-
Hive将SQL翻译成MapReduce,降低大数据分析门槛。
-
Metastore是Hive的核心,推荐使用MySQL存储元数据。
-
Driver负责SQL的解析、优化和计划生成。
-
内部表 和外部表的区别在于Hive是否管理数据。
-
DDL 定义数据结构,DML操作数据内容。
Hive的优势:
-
类SQL语法,学习成本低
-
与Hadoop生态无缝集成
-
支持自定义函数和存储格式
-
适合大规模数据批处理