前哨站/第7章 Hive实战
第7章 Hive实战

第7章 Hive实战

把 SQL 能力搬到 Hadoop 上:Hive 的存储格式、数据类型、HiveQL、自定义函数与 Sqoop 数据迁移。

数据仓库HiveQLSqoop

本章学习目标

  • 能说出 Hive 的定位、文件存储格式与数据类型
  • 能安装并验证 Hive(含 MySQL 元数据库)
  • 能用 HiveQL 完成库表操作、查询、索引与视图
  • 能使用复合数据类型与编写 UDF/UDAF
  • 能用 Sqoop 在 MySQL 与 Hive 之间迁移数据

本章导览

核心内容

7.1

Hive概述

Hive 是构建在 Hadoop 之上的数据仓库工具:把 HDFS 上的文件映射成表,把 HiveQL 翻译成 MapReduce/Tez 作业执行。

与《Hive数据仓库工具》课程的关系:本课程只覆盖教材第7章的"Hive 入门 + HiveQL 要点";建表全子句、分区分桶、物化视图、窗口函数、性能优化等内容,请到 Hive数据仓库工具学习网站 继续学习。
7.1.2

Hive的文件存储格式

格式类型特点
TEXTFILE行存可读性好、压缩率低,适合导入与小数据
ORC列存压缩率高、查询快,Hive 官方推荐
PARQUET列存跨平台兼容性好,适合与 Spark 共用
7.1.3

Hive支持的数据类型

类别类型
基本类型TINYINT / SMALLINT / INT / BIGINT / FLOAT / DOUBLE / BOOLEAN / STRING / TIMESTAMP
复合类型ARRAY、MAP、STRUCT、UNIONTYPE
SHELL
CREATE TABLE t_complex(
    id      INT,
    hobbies ARRAY<STRING>,          -- 数组
    scores  MAP<STRING, INT>,       -- 键值对
    info    STRUCT<name:STRING, age:INT>
) ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '|'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
7.2

安装与验证Hive

两条依赖:元数据库(MySQL)与 HDFS。装完用 <code class="inl">schematool -initSchema</code> 初始化元数据,再用 <code class="inl">show databases;</code> 验证。

7.2.2

安装和配置Hive

SHELL
# 1) 解压并配置环境变量
tar -zxvf apache-hive-4.1.0-bin.tar.gz -C /export/servers/
vi ~/.bashrc
export HIVE_HOME=/export/servers/hive-4.1.0
export PATH=$HIVE_HOME/bin:$PATH

# 2) 修改 hive-site.xml:指定 MySQL 元数据库
<property><name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://hadoop1:3306/hive?createDatabaseIfNotExist=true</value></property>
<property><name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.cj.jdbc.Driver</value></property>
<property><name>hive.metastore.warehouse.dir</name>
  <value>/user/hive/warehouse</value></property>

# 3) 放 MySQL 驱动并初始化元数据
cp mysql-connector-java-8.0.30.jar $HIVE_HOME/lib/
schematool -initSchema -dbType mysql

# 4) 验证
hive -e "show databases;"
7.3

HiveQL详解

教材按"数据库操作 → 表操作 → 数据查询 → 索引和视图"四块讲,覆盖日常开发 80% 的用法。

7.3.2

表操作

SHELL
CREATE TABLE IF NOT EXISTS student_info(
    stu_id   STRING COMMENT '学号',
    stu_name STRING COMMENT '姓名',
    sex      STRING COMMENT '性别'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS ORC;

-- 内部表 vs 外部表
CREATE EXTERNAL TABLE ext_student(...) LOCATION '/data/student';

-- 分区表
CREATE TABLE score_part(stu_id STRING, score INT)
PARTITIONED BY (course_id STRING);

-- 常用维护
DESC FORMATTED student_info;
SHOW PARTITIONS score_part;
ALTER TABLE student_info ADD COLUMNS (class_id STRING);
TRUNCATE TABLE student_info;
7.3.3

数据查询

SHELL
-- 基础查询
SELECT stu_name, sex FROM student_info WHERE sex = '男';

-- 分组统计
SELECT course_id, count(*) AS cnt, round(avg(score), 2) AS avg_score
FROM score_info GROUP BY course_id HAVING avg(score) > 60;

-- 多表连接
SELECT s.stu_name, c.course_name, sc.score
FROM score_info sc
JOIN student_info s ON sc.stu_id = s.stu_id
JOIN course_info  c ON sc.course_id = c.course_id;

-- 窗口函数:取每门课前 3 名
SELECT * FROM (
  SELECT course_id, stu_id, score,
         rank() OVER (PARTITION BY course_id ORDER BY score DESC) rk
  FROM score_info
) t WHERE rk <= 3;
7.5

用户自定义函数

内置函数不够用时自己写:UDF 一行进一行出,UDAF 多行进一行出。

7.5.1

编写UDF

JAVA
public class MyLowerUDF extends UDF {
    public Text evaluate(Text input) {
        if (input == null) return null;
        return new Text(input.toString().toLowerCase());
    }
}
SHELL
-- 注册与使用
ADD JAR /user/hadoop/jars/myudf.jar;
CREATE TEMPORARY FUNCTION my_lower AS 'com.demo.MyLowerUDF';
SELECT my_lower(stu_name) FROM student_info LIMIT 5;
7.7

数据迁移工具Sqoop

Sqoop 用 MapReduce 在关系型数据库与 HDFS/Hive 之间批量搬运数据,是"业务库 → 数仓"的标准通道。

7.7.2

MySQL数据导入Hive

SHELL
sqoop import \
  --connect jdbc:mysql://hadoop1:3306/nev --username root --password 123456 \
  --table web_chat_ems --hive-import --hive-database ods --hive-table web_chat_ems \
  --fields-terminated-by '\t' -m 1
SHELL
-- 反向:Hive 导出到 MySQL(目标表需先建好)
sqoop export \
  --connect jdbc:mysql://hadoop1:3306/nev --username root --password 123456 \
  --table visit_dws \
  --export-dir /user/hive/warehouse/dws.db/visit_dws \
  --input-fields-terminated-by '\t'
  -- 注意:导出前请确认 MySQL 端已建好同结构的接收表

本章小结

本章是教材里与数据仓库直接相关的一章:先讲 Hive 的定位、存储格式与数据类型,再完成安装与元数据初始化,然后用库表操作、查询、索引视图覆盖 HiveQL 主干,接着讲复合数据类型与 UDF/UDAF,最后用 Sqoop 打通 MySQL 与 Hive 的导入导出。

思考与练习 先自己做,再点开答案

01

Hive 中内部表与外部表的区别?

查看参考答案

内部表由 Hive 管理数据,DROP TABLE 时元数据与数据一起删除;外部表只删元数据,HDFS 上的数据保留。接别人的数据一律用外部表。

02

为什么 Hive 查询比 MySQL 慢,却更适合大数据?

查看参考答案

Hive 把 SQL 翻译成分布式作业(MapReduce/Tez),启动开销大、延迟高(分钟级),但可以横向扩展到成百上千节点处理 TB/PB 级数据;MySQL 单机毫秒级响应,但数据量到 GB/TB 级别就撑不住。

03

UDF 与 UDAF 的区别?

查看参考答案

UDF(User Defined Function)一行输入一行输出,如大小写转换;UDAF(User Defined Aggregation Function)多行输入一行输出,如自定义求和/求均值。

04

Sqoop 导入时为什么常加 -m 1?

查看参考答案

-m 1 表示只用 1 个 Map 任务,避免导出多个文件、也避免 MySQL 端压力过大;数据量大时可按主键切分多个 Map 并行导入。