来源:
Ahive.txt。本页按题型整理为选择题、简答启动步骤、图书库建表练习和在线音乐平台综合查询。
1. 选择题
1.1 未编号题
Hive 的元数据存储在 Derby 和 MySQL 中的区别是( )。
- A. 没区别
- B. 多会话
- C. 支持网络环境
- D. 数据库的区别
答案:B
下面不属于 Hive 中的元数据信息的是( )。
- A. 表的名字
- B. 表的列和分区及其属性
- C. 表的属性(只存储内部表信息)
- D. 表的数据所在目录
答案:C
1.2 编号题
1. Hive 是以( )技术为基础的数据仓库。
- A. HDFS
- B. MapReduce
- C. Hadoop
- D. HBase
答案:C
2. Hive 存储元数据的服务是( )。
- A. HDFS
- B. Metastore
- C. ZooKeeper
- D. HBase
答案:B
3. Hive 是基于( )为计算引擎的。
- A. Spark
- B. MapReduce
- C. HDFS
- D. HQL
答案:B
4. 以下不属于 Hive 文件格式的是( )。
- A. TextFile 格式
- B. SequenceFile 格式
- C. RCFile 格式
- D. ORC 格式
答案:D
5. 下面关于 Hive 内部表和外部表描述正确的是( )。
- A. Hive 内部表的元数据和数据都由 Hive 自己管理。
- B. Hive 不会管理外部表的元数据。
- C. 当 Hive 内部表的元数据发生变化时,内部表的修改不会同步给元数据。
- D. 对外部表的表结构和分区进行修改,不需要修复。
答案:A
6. 以下关于 HiveSQL 基本操作描述正确的是( )。
- A. 创建外部表必须要指定 location 信息。
- B. 创建外部表使用 external 关键字,创建普通表需要指定 internal 关键字。
- C. 创建表时可以指定列分隔符。
- D. 加载数据到 Hive 时,源数据必须是 HDFS 的一个路径。
答案:C
7. 关于 Hive 中的桶说法不正确的是( )。
- A. 每个桶是一个目录。
- B. 建表时指定桶个数,桶内可排序。
- C. 数据按照某个字段的值 Hash 后放入某个桶中。
- D. 对于数据抽样、特定 join 的优化很有意义。
答案:A
8. Hive 的元数据存储在 Derby 和 MySQL 中的区别是( )。
- A. 没区别
- B. 多会话
- C. 支持网络环境
- D. 数据库的区别
答案:B
9. 下面不属于 Hive 中的元数据信息的是( )。
- A. 表的名字
- B. 表的列和分区及其属性
- C. 表的属性(只存储内部表信息)
- D. 表的数据所在目录
答案:C
12. 下面关于 HiveQL 中 insert into 和 insert overwrite 的区别,说法不正确的是( )。
- A.
insert into不会覆盖已经存在的数据。 - B.
insert overwrite会先将原始表的数据删除,再插入新数据。 - C.
insert into不考虑原始数据,直接追加到表中。 - D.
insert into重复的数据会报错。
答案:D
13. Hive 中分组的关键字是( )。
- A.
group by - B.
order by - C.
distribute by - D.
sort by
答案:A
14. 已知数组 trans_cnt[1,2,3,4],trans_cnt[2] 获取的结果为( )。
- A. 1
- B. 2
- C. 3
- D. 4
答案:C
15. 在 Hive 中不可以实现去重的命令是( )。
- A.
distinct - B.
group by - C.
row_number - D.
having
答案:D
16. 外连接进行 join 默认在( )。
- A. Map 端
- B. Reduce 端
- C. External 端
- D. Shuffle 端
答案:B
2. 简答题:启动 Hive 服务
cd /usr/local/hadoop-2.6.5/sbin
./start-all.sh
cd /usr/local/apache-hive-1.2.1-bin/bin
./hive --service metastore &
./hive --service hiveserver2 &
./hive
3. 图书库建表与数据导入
3.1 创建并使用 library 数据库
CREATE DATABASE IF NOT EXISTS library;
USE library;
3.2 创建内部表 books
字段包含
book_id、book_title、author,字段分隔符为制表符,文件格式为
SequenceFile。
CREATE TABLE books (
book_id INT,
book_title STRING,
author STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS SEQUENCEFILE;
3.3 创建外部表 borrow_records
字段包含 record_id、book_id,分区字段为
borrow_date,字段分隔符为逗号,文件格式为
TextFile,数据位置为 /hive_data/records。
CREATE EXTERNAL TABLE borrow_records (
record_id INT,
book_id INT
)
PARTITIONED BY (borrow_date STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/hive_data/records';
3.4 导入 books 并查询指定作者
LOAD DATA LOCAL INPATH '/opt/books_data.txt'
INTO TABLE books;
SELECT *
FROM books
WHERE author = 'J.K.Rowling';
3.5 导入 borrow_records 分区并查看前 10 行
LOAD DATA INPATH '/borrow/data.txt'
INTO TABLE borrow_records
PARTITION (borrow_date = '2026-06-06');
SELECT *
FROM borrow_records
LIMIT 10;
4. 在线音乐平台综合查询
4.1 表结构
用户表 dim_users
| 字段 | 类型 | 说明 |
|---|---|---|
user_id |
string |
用户编号 |
user_name |
string |
用户名 |
register_date |
string |
注册日期 |
country |
string |
国家 |
tags |
array<string> |
标签,如 ["premium", "family"] |
profile |
map<string, string> |
扩展属性,如 {"age":"22", "gender":"F"} |
vip_level |
int |
VIP 等级,取值范围 0-5 |
歌曲表 dim_songs
| 字段 | 类型 | 说明 |
|---|---|---|
song_id |
string |
歌曲编号 |
song_name |
string |
歌曲名称 |
genre_l1 |
string |
一级流派 |
genre_l2 |
string |
二级流派 |
price |
double |
单曲订阅价格 |
singer |
string |
歌手 |
订阅支付记录表 fact_subscriptions
| 字段 | 类型 | 说明 |
|---|---|---|
sub_id |
string |
订阅记录号 |
user_id |
string |
用户编号 |
song_id |
string |
歌曲编号 |
sub_date |
string |
订阅支付日期 |
duration |
int |
订阅时长,单位:天数 |
pay_amount |
double |
实际支付金额 |
status |
string |
状态:completed、expired |
退订表 fact_unsubscribes
| 字段 | 类型 | 说明 |
|---|---|---|
unsub_id |
string |
退订单号 |
sub_id |
string |
原订阅记录号 |
unsub_date |
string |
退订申请日期 |
reason |
string |
退订原因 |
4.2 查询高等级 VIP 用户
查询 VIP 等级大于等于 4 的用户编号、用户名、国家以及
profile 中的年龄,年龄提取为整数,无法转换时显示
NULL。
SELECT
user_id,
user_name,
country,
CAST(profile['age'] AS INT) AS age_int
FROM dim_users
WHERE vip_level >= 4;
4.3 统计 pop 歌手订阅金额 Top 5
查询二级流派为 pop
的歌曲中,每个歌手的总订阅支付金额以及订阅记录数,按总金额降序取前 5
名。
SELECT
ds.singer,
SUM(fs.pay_amount) AS total_pay,
COUNT(*) AS record_cnt
FROM fact_subscriptions fs
JOIN dim_songs ds
ON ds.song_id = fs.song_id
WHERE ds.genre_l2 = 'pop'
GROUP BY ds.singer
ORDER BY total_pay DESC
LIMIT 5;
4.4 找出曾被退订过至少一次的歌曲
通过订阅记录关联退订表,输出歌曲编号、歌曲名称、退订次数。
SELECT
ds.song_id,
ds.song_name,
COUNT(fu.unsub_id) AS unsub_count
FROM fact_subscriptions fs
JOIN fact_unsubscribes fu
ON fs.sub_id = fu.sub_id
JOIN dim_songs ds
ON ds.song_id = fs.song_id
GROUP BY ds.song_id, ds.song_name
HAVING COUNT(fu.unsub_id) >= 1;
4.5 找出首单订阅支付金额超过 50 元的用户
输出用户编号、用户名、首单支付金额、首单订阅日期。首单定义为按
sub_date
升序的第一条订阅支付记录,假设同一天只有一条记录。
WITH first_order_date AS (
SELECT
user_id,
MIN(sub_date) AS first_date
FROM fact_subscriptions
GROUP BY user_id
)
SELECT
u.user_id,
u.user_name,
o.pay_amount AS first_amount,
o.sub_date AS first_date
FROM dim_users u
JOIN first_order_date f
ON u.user_id = f.user_id
JOIN fact_subscriptions o
ON o.user_id = f.user_id
AND o.sub_date = f.first_date
WHERE o.pay_amount > 50;