Hive 数据仓库技术全解(一):环境搭建、服务配置与核心DDL/DML/DQL基础
Hive 数据仓库技术全解(一):环境搭建、服务配置与核心DDL/DML/DQL基础
作者:Lijingang
日期:2026-07-10
标签:HiveHadoop大数据SQLMapReduce
前言
在大数据生态体系中,Apache Hive 扮演着至关重要的角色。它是构建在 Hadoop 之上的数据仓库工具,能将结构化数据映射为一张张表,并提供类 SQL(HQL)的查询能力。Hive 的核心价值在于:将 HQL 语句翻译为 MapReduce 任务,在 YARN 上执行,数据在 HDFS 上读写(当前生产环境常将执行引擎切换为 Tez 或 Spark 以提升性能,本文先以底层原理最通用的 MapReduce 进行解析。),从而让不懂 Java MapReduce 编程的开发者也能轻松处理海量数据。
本文将从环境搭建、架构原理、HQL 基础语法,系统性地梳理 Hive 技术栈,助你全面掌握这个大数据利器。
本文为《Hive数据仓库技术全解》系列的第一篇,聚焦于环境搭建、服务配置、DDL(库表操作)和基础DML/DQL语法。后续文章预告:
第二篇:HQL高级函数(窗口函数、UDF/UDAF/UDTF、炸裂函数与行列转换,分区/分桶)
第三篇:企业级生产调优(聚合优化、数据倾斜优化、小文件合并、join优化等)
—**
一、Hive 环境搭建
1.1 安装 Hive 框架
<>符号表示根据自己的安装情况自行配置
第一步,下载并安装 Hive 框架,配置环境变量。
#java环境变量
export JAVA_HOME=/<java安装路径>
export PATH=$PATH:$JAVA_HOME/bin
#hadoop环境变量
export HADOOP_HOME=/<hadoop安装路径>
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# hive
export HIVE_HOME=/<hive安装路径>
export PATH=$PATH:$HIVE_HOME/bin
1.2 配置 Hive 与 Hadoop 关联
Hive 需要与 Hadoop 协同工作 —— 将 SQL 翻译成 MapReduce 程序在 YARN 上运行,数据也在 HDFS 上读取和保存。核心配置如下:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 配置 Hive 在 HDFS 中的工作目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- JDBC 连接的 URL -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://<ip地址>:<端口>/metastore?useSSL=false</value>
</property>
<!-- MySQL 驱动类 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- MySQL 连接的用户名 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
</configuration>
1.3 元数据存储 —— 对接 MySQL
Hive 自带的 Derby 数据库只适合本地测试,生产环境中需要将元数据存储在 MySQL 中。关键步骤如下:
- 在 Linux 上安装 MySQL,使用临时密码登录并修改密码
- 执行元数据库初始化命令:
schematool -dbType mysql -initSchema -verbose
- 将 MySQL 驱动 jar 包放入 Hive 的
lib目录下
二、Hive 工作流程
Hive 将 SQL 语句翻译为 MR 任务交给 YARN 执行,并在 HDFS 上读写文件,同时还负责保存 HDFS 文件的元数据。这套机制极大提升了开发效率 —— 开发者只需写 SQL,Hive 负责将其高效地转换为分布式计算任务。

核心流程可概括为:
用户提交 HQL → Driver 解析 SQL → Compiler 生成执行计划
→ Optimizer 优化 → Executor 提交 MR 任务到 YARN
→ 读写 HDFS 文件 → 返回结果
三、配置 Hive 服务
3.1 HiveServer2 远程连接
若需要远程连接 Hive(如通过 DataGrip、JDBC 等),必须开启 HiveServer2 服务。
第一步:配置 Hadoop 的 core-site.xml,设置代理用户权限,使 HiveServer2 可以直接操作 NameNode 和 ResourceManager:
<!-- 配置所有节点的指定用户都可以作为代理用户 -->
<property>
<name>hadoop.proxyuser.<用户>.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.<用户>.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.<用户>.users</name>
<value>*</value>
</property>
配置完成后需要分发到所有集群节点。
第二步:配置 Hive 的 hive-site.xml,指定 HiveServer2 的主机和端口:
<property>
<name>hive.server2.thrift.bind.host</name>
<value><ip地址></value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value><port端口号></value>
</property>
第三步:配置 Metastore 服务独立运行:
<property>
<name>hive.metastore.uris</name>
<value>thrift://<ip地址>:9083</value>
</property>
3.2 后台启动服务
HiveServer2 和 Metastore 服务启动时会独占窗口,通常使用 nohup 后台运行:
nohup hive --service metastore 1>/opt/module/hive-3.1.3/logs/metastore-log 2>&1 &
nohup hive --service hiveserver2 1>/opt/module/hive-3.1.3/logs/hiveserver2-log 2>&1 &
命令解释:
nohup— 关闭终端不会 kill 进程1>log_path 2>&1— 重定向 stdout 和 stderr 到日志文件&— 进程在后台运行
3.3 其他实用配置
日志目录配置:修改 hive-log4j2.properties.template 中的日志路径,并重命名为 hive-log4j2.properties:
property.hive.log.dir = /opt/module/hive-3.1.3/logs
本地模式:日常测试不想跑集群时,可临时切换为本地模式:
set mapreduce.framework.name=local;
本地模式可能会有内存溢出问题。需修改
hive-env.sh增加 HeapSize 到 2048MB。
四、Hive 客户端使用技巧
4.1 交互式命令
# 执行单条 SQL 后退出
hive -e "SELECT * FROM emp LIMIT 10;"
# 执行整个 SQL 文件后退出
hive -f /path/to/query.sql
4.2 临时修改配置
# 启动时指定配置
hive --hiveconf mapreduce.framework.name=local
# 进入命令行后修改
hive> set mapreduce.framework.name=local;
hive> set mapreduce.framework.name; -- 查看当前值
五、HQL 基础语法(重点)
以下所有示例基于本地练习环境。
5.1 数据类型
基本数据类型
CREATE TABLE student (
id INT,
name STRING,
id_card BIGINT,
sal DOUBLE
);
INSERT INTO student VALUES
(1001, 'zhangsan', 238791939, 38000.00),
(1002, 'lisi', 28379123909, 32000.00);
| 类型 | 说明 | 示例 |
|---|---|---|
| INT | 整数 | 1001 |
| BIGINT | 长整数 | 28379123909 |
| STRING | 字符串 | ‘zhangsan’ |
| DOUBLE | 双精度浮点 | 38000.00 |
集合数据类型
Hive 相对于传统关系型数据库,提供了丰富的集合类型 —— ARRAY、MAP、STRUCT:
-- 数据样例:周杰伦, xiaoming_xiaomei, 青花瓷:29.99_告白气球:32.00, 南山区_深圳_12298
CREATE TABLE singers (
name STRING,
friends ARRAY<STRING>, -- ["xiaoming", "xiaomei"]
songs MAP<STRING, DOUBLE>, -- {"青花瓷": 29.99, "告白气球": 32.00}
address STRUCT<region:STRING, city:STRING, post_code:BIGINT>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '_'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';
-- 查询集合字段
SELECT name, friends[0], songs['青花瓷'], address.region FROM singers;
| 类型 | 说明 | 示例 |
|---|---|---|
| ARRAY | 数组(元素数据类型相同) | array(1,2,3,4,5) |
| MAP | 键值对(key数据类型相同,value数据类型相同) | map(‘key1’, ‘value1’, ‘key2’, ‘value2’) |
| STRUCT | 结构体,类似Java对象 | named_struct(‘name’, ‘zhangsan’, ‘age’, 18, ‘sex’, ‘男’) |
5.2 DDL —— 数据库与表定义
创建数据库
CREATE DATABASE IF NOT EXISTS db1
COMMENT '练习使用的库'
LOCATION '/db1'
WITH DBPROPERTIES ('author'='zhangsan', 'create_time'='2026/3/23');
建表语法全览
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, ...)] -- 分区
[CLUSTERED BY (col_name, ...) INTO N BUCKETS] -- 分桶
[SORTED BY (col_name [ASC|DESC], ...)] -- 桶内排序
[ROW FORMAT row_format]
[STORED AS file_format] -- 存储格式(textfile / orc / parquet)
[LOCATION hdfs_path]
[TBLPROPERTIES (key=val, ...)]
[AS select_statement]; -- CTAS 建表
内部表 vs 外部表
| 特性 | 内部表 (Managed Table) | 外部表 (External Table) |
|---|---|---|
| 数据生命周期 | 随表删除而删除 | 删除表时数据保留 |
| 适用场景 | 仅由 Hive 管理的数据 | 多工具共享的 HDFS 数据 |
-- 内部表
CREATE TABLE student (id INT, name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 外部表
CREATE EXTERNAL TABLE student1 (id INT, name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
表结构修改
-- 重命名
ALTER TABLE singer1 RENAME TO singer3;
-- 新增列
ALTER TABLE singer1 ADD COLUMNS (salary DOUBLE);
-- 修改列
ALTER TABLE singer1 CHANGE COLUMN salary sal DOUBLE;
-- 替换列(慎用,会覆盖所有列)
ALTER TABLE singer1 REPLACE COLUMNS (name1 STRING, friend ARRAY<STRING>);
-- 清空表
TRUNCATE TABLE singer3;
-- 删除表
DROP TABLE singer2;
5.3 DML —— 数据操作
Load 导入
LOAD DATA [LOCAL] INPATH '/path/to/data.txt'
[OVERWRITE] INTO TABLE table_name;
LOCAL:从本地(Hive 服务器)上传OVERWRITE:覆盖写入
Insert 导入
-- 追加((注意:每次INSERT INTO会生成新文件,生产环境建议配合分区使用))
INSERT INTO TABLE student1 SELECT * FROM student;
-- 覆盖
INSERT OVERWRITE TABLE student1 SELECT * FROM student;
-- 将查询结果导出到本地/HDFS
INSERT OVERWRITE LOCAL DIRECTORY '/export/path'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
SELECT * FROM student;
Export / Import 数据导出导入
-- 导出(含元数据,仅支持 HDFS)
EXPORT TABLE student TO '/data/student';
-- 导入(创建新表并恢复数据)
IMPORT TABLE new_student FROM '/data/student';
5.4 DQL —— 数据查询
以经典的 emp(员工表)和 dept(部门表)为例:
-- 部门表
CREATE TABLE dept (
deptno INT COMMENT '部门编号',
dname STRING COMMENT '部门名称',
loc INT COMMENT '部门位置'
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 员工表
CREATE TABLE emp (
empno INT COMMENT '员工编号',
ename STRING COMMENT '员工姓名',
job STRING COMMENT '员工岗位',
sal DOUBLE COMMENT '员工薪资',
deptno INT COMMENT '部门编号'
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
JOIN 连接查询
-- 内连接:两表交集
SELECT e.*, d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno;
-- 左外连接:左表全部 + 右表交集
SELECT e.*, d.dname
FROM emp e
LEFT JOIN dept d ON e.deptno = d.deptno;
-- 右外连接:左表交集 + 右表全部
SELECT e.*, d.dname
FROM emp e
RIGHT JOIN dept d ON e.deptno = d.deptno;
-- 全连接:两表全部
SELECT e.*, d.dname
FROM emp e
FULL JOIN dept d ON e.deptno = d.deptno;
-- 多表联查
SELECT e.*, d.dname, l.loc_name
FROM emp e
JOIN dept d ON e.deptno = d.deptno
JOIN location l ON d.loc = l.loc;
分组聚合
-- 每个部门的平均薪资
SELECT deptno, AVG(sal) AS avg_sal
FROM emp
GROUP BY deptno;
-- 每个部门最高薪水的人
SELECT t1.deptno, t1.max_sal, t2.ename
FROM (
SELECT deptno, MAX(sal) AS max_sal
FROM emp
GROUP BY deptno
) t1
JOIN emp t2 ON t1.deptno = t2.deptno AND t1.max_sal = t2.sal;
排序
-- 全局排序(Order By):有且仅有一个 Reduce
SELECT * FROM emp ORDER BY deptno;
-- 区内排序(Sort By):每个 Reduce 内部排序,配合 DISTRIBUTE BY 控制分区
SELECT * FROM emp
DISTRIBUTE BY deptno -- 按 deptno 哈希分区
SORT BY deptno;
-- CLUSTER BY = DISTRIBUTE BY + SORT BY(同一字段,仅升序)
SELECT * FROM emp CLUSTER BY deptno;
更多推荐



所有评论(0)