来源: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_idbook_titleauthor,字段分隔符为制表符,文件格式为 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_idbook_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 状态:completedexpired

退订表 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;