目 录
一、实验目的
二、实验环境
三、数据集
四、实验内容与完成情况
4.1 创建一个内部表 stocks,字段分隔符为英文逗号,表结构下所示。
4.2 创建一个外部分区表 dividends(分区字段为 exchange 和symbol),字段分隔符为英文逗号,表结构如表下所示。
4.3 从 stocks.csv 文件向 stocks 表中导入数据。
4.4 创建一个未分区的外部表 dividends_unpartitioned,并从dividends.csv 向其中导入数 据,表结构如下所示。
4.5 通过对 dividends_unpartitioned 的查询语句,利用 Hive 自动分区特性向分区表 dividends 各个分区中插入对应数据。
4.6 查询 IBM 公司(symbol=IBM)从 2000 年起所有支付股息的交易日(dividends 表中有对应 记录)的收盘价(price_close)。
4.7 查询苹果公司(symbol=AAPL)2008 年 10 月每个交易日的涨跌情况,涨显示 rise,跌显 示 fall,不变显示 unchange。
4.8 查询 stocks 表中收盘价(price_close)比开盘价(price_open)高得最多的那条记录的交易所 (exchange)、股票代码(symbol)、日期(ymd)、收盘价、开盘价及二者差价。
4.9 从 stocks 表中查询苹果公司(symbol=AAPL)年平均调整后收盘价(price_adj_close) 大 于 50 美元的年份及年平均调整后收盘价。
4.10 查询每年年平均调整后收盘价(price_adj_close)前三名的公司的股票代码及年平均调整 后收盘价。
四、问题和解决方法
五、心得体会
一、实验目的
1. 理解 Hive 作为数据仓库在 Hadoop 体系结构中的角色。
2. 熟练使用常用的 HiveQL。
二、实验环境
1. 硬件要求:笔记本电脑一台
2. 软件要求:VMWare虚拟机、Ubuntu 18.04 64、JDK1.8、Hadoop-3.1.3、Hive-3.1.2、Windows11操作系统、Eclipse
三、数据集
由《Hive 编程指南》(O'Reilly 系列,人民邮电出版社)提供,下载地址:
https://raw.githubusercontent.com/oreillymedia/programming_hive/master/prog-hive-1st-ed-data.zip
备用下载地址:
https://www.cocobolo.top/FileServer/prog-hive-1st-ed-data.zip
解压后可以得到本实验所需的 stocks.csv 和 dividends.csv 两个文件。
四、实验内容与完成情况
4.1 创建一个内部表 stocks,字段分隔符为英文逗号,表结构下所示。
(1)进入/opt目录,使用以下Shell命令解压apache-hive-3.1.0-bin.tar.gz到该目录下。
cd /opttar -zxvf apache-hive-3.1.0-bin.tar.gz
(2)使用以下Shell命令将解压的文件重命名为hive。
mv apache-hive-3.1.0-bin hive
(3)使用以下Shell命令设置环境变量,在末尾添加对应的配置信息。
vi /etc/profileexport HIVE_HOME=/opt/hiveexport PATH=$HIVE_HOME/bin:$PATH
(4)使用以下Shell命令使配置信息立即生效。
source /etc/profile
(5)使用以下Shell命令查看hive是否安装成功。
hive --version
(6)使用以下Shell命令安装mysql服务。
sudo apt-get install mysql-server
(7)使用以下Shell命令安装mysql客户端。
apt-get install mysql-client
(8)使用以下Shell命令安装相关依赖环境。
sudo apt-get install libmysqlclient-dev
(9)使用以下Shell命令在/opt/hive/conf目录下,修改hive-site.xml配置文件。
cd /opt/hive/confvi hive-site.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration><property><name>hive.metastore.warehouse.dir</name><value>/usr/local/hive/warehouse</value><description>location of default database for the warehouse</description></property><property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:mysql://localhost:3306/hive;createDatabaseIfNotExist=true</value><description>JDBC connect string for a JDBC metastore</description></property><property><name>javax.jdo.option.ConnectionDriverName</name><value>com.mysql.jdbc.Driver</value><description>Driver class name for a JDBC metastore</description></property><property><name>javax.jdo.option.ConnectionPassword</name><value>hive</value></property><property><name>javax.jdo.option.ConnectionUserName</name><value>hive</value><description>Username to use against metastore database</description></property>
</configuration>
(10)使用以下Shell命令在/opt/hive/conf目录下,修改hive-env.sh配置文件。
vi hive-env.shHADOOP_HOME=/usr/local/hadoop
(11)使用以下Shell命令启动hive。
hive
(12)使用以下语句创建内部表stocks,字段分隔符为英文逗号。
CREATE TABLE IF NOT EXISTS stocks
(
`exchange` STRING,
`symbol` STRING,
`ymd` STRING,
`price_open` FLOAT,
`price_high` FLOAT,
`price_low` FLOAT,
`price_close` FLOAT,
`volume` INT,
`price_adj_close` FLOAT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
4.2 创建一个外部分区表 dividends(分区字段为 exchange 和symbol),字段分隔符为英文逗号,表结构如表下所示。
使用以下语句创建外部分区表dividends(分区字段为exchange和symbol),字段分隔符为英文逗号。
CREATE EXTERNAL TABLE IF NOT EXISTS dividends
(
`ymd` STRING,
`dividend` FLOAT
)
PARTITIONED BY (`exchange` STRING, `symbol` STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
4.3 从 stocks.csv 文件向 stocks 表中导入数据。
使用以下语句从stocks.csv文件向stocks表中导入数据。
load data local inpath '/home/hadoop/data/stocks/stocks.csv' overwrite into table stocks;
4.4 创建一个未分区的外部表 dividends_unpartitioned,并从dividends.csv 向其中导入数 据,表结构如下所示。
(1)使用以下语句创建一个未分区的外部表dividends_unpartitioned。
CREATE EXTERNAL TABLE IF NOT EXISTS dividends_unpartitioned
(
`exchange` STRING,
`symbol` STRING,
`ymd` STRING,
`dividend` FLOAT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
(2)使用以下语句从dividends.csv文件向dividends_unpartitioned表中导入数据。
load data local inpath '/home/hadoop/data/dividends/dividends.csv' overwrite into table dividends_unpartitioned;
4.5 通过对 dividends_unpartitioned 的查询语句,利用 Hive 自动分区特性向分区表 dividends 各个分区中插入对应数据。
使用以下语句通过对dividends_unpartitioned的查询语句,利用Hive自动分区特性向分区表dividends各个分区中插入对应数据。
set hive.exec.dynamic.partition=true;set hive.exec.dynamic.partition.mode=nonstrict;set hive.exec.max.dynamic.partitions.pernode=1000;insert overwrite table dividends partition(`exchange`,`symbol`) select `ymd`,`dividend`,`exchange`,`symbol` from dividends_unpartitioned;
4.6 查询 IBM 公司(symbol=IBM)从 2000 年起所有支付股息的交易日(dividends 表中有对应 记录)的收盘价(price_close)。
使用以下语句查询IBM公司(symbol=IBM)从2000年起所有支付股息的交易日(dividends表中有对应记录)的收盘价(price_close)。
select s.ymd,s.symbol,s.price_closefrom stocks sLEFT SEMI JOINdividends dON s.ymd=d.ymd and s.symbol=d.symbolwhere s.symbol='IBM' and year(ymd)>=2000;
4.7 查询苹果公司(symbol=AAPL)2008 年 10 月每个交易日的涨跌情况,涨显示 rise,跌显 示 fall,不变显示 unchange。
使用以下语句查询苹果公司(symbol=AAPL)2008年10月每个交易日的涨跌情况,涨显示rise,跌显示fall,不变显示unchange。
SELECT ymd,
CASE
WHEN price_close - price_open > 0 THEN 'rise'
WHEN price_close - price_open < 0 THEN 'fall'
ELSE 'unchanged'
END AS situation
FROM stocks
WHERE symbol = 'AAPL'
AND SUBSTRING(ymd, 0, 7) = '2008-10';
4.8 查询 stocks 表中收盘价(price_close)比开盘价(price_open)高得最多的那条记录的交易所 (exchange)、股票代码(symbol)、日期(ymd)、收盘价、开盘价及二者差价。
使用以下语句查询stocks表中收盘价(price_close)比开盘价(price_open)高得最多的那条记录的交易所(exchange)、股票代码(symbol)、日期(ymd)、收盘价、开盘价及二者差价。
SELECT `exchange`, symbol, ymd, price_close - price_open AS `diff`
FROM (
SELECT *
FROM stocks
ORDER BY price_close - price_open DESC
LIMIT 1
) t;
4.9 从 stocks 表中查询苹果公司(symbol=AAPL)年平均调整后收盘价(price_adj_close) 大 于 50 美元的年份及年平均调整后收盘价。
使用以下语句从stocks表中查询苹果公司(symbol=AAPL)年平均调整后收盘价(price_adj_close)大于50美元的年份及年平均调整后收盘价。
SELECT
YEAR(ymd) AS `year`,
AVG(price_adj_close) AS avg_price
FROM stocks
WHERE `exchange` = 'NASDAQ' AND symbol = 'AAPL'
GROUP BY YEAR(ymd)
HAVING avg_price > 50;
4.10 查询每年年平均调整后收盘价(price_adj_close)前三名的公司的股票代码及年平均调整 后收盘价。
使用以下语句查询每年年平均调整后收盘价(price_adj_close)前三名的公司的股票代码及年平均调整后收盘价。
SELECT t2.`year`, symbol, t2.avg_price
FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY t1.`year` ORDER BY t1.avg_price DESC) AS `rank`
FROM
(
SELECT
YEAR(ymd) AS `year`,
symbol,
AVG(price_adj_close) AS avg_price
FROM stocks
GROUP BY YEAR(ymd), symbol
) t1
) t2
WHERE t2.`rank` <= 3;
四、问题和解决方法
1. 实验问题:Hadoop无法启动或启动失败。
解决方法:检查Hadoop配置文件中的路径和参数设置,确保正确设置以及文件的可访问性,对配置文件进行修改后对应问题得到解决。
2. 实验问题:Hadoop的任务无法运行或失败。
解决方法:检查任务配置文件中的输入输出路径是否正确,并确保输入数据存在,更改输入输出路径后问题得到解决。
3. 实验问题:执行命令时提示"命令未找到"。
解决方法:确保命令拼写正确,并检查命令是否安装在系统路径中。可以使用which命令来确定命令的路径,并将其添加到系统路径中。
4. 实验问题:没有足够的权限执行某个命令。
解决方法:尝试使用sudo命令以管理员权限运行命令,或者联系系统管理员赋予所需的权限。
5. 实验问题:如何在Hive中创建一个内部表stocks。
解决方法:使用CREATE TABLE语句进行内部表stocks的创建。
6. 实验问题:如何从stocks.csv文件向stocks表中导入数据。
解决方法:使用LOAD DATA语句并将stocks.csv文件加载到stocks表中。
7. 实验问题:如何在Hive中创建一个未分区的外部表dividends_unpartitioned,并从dividends.csv向其中导入数据,并指定表结构。
解决方法:使用CREATE TABLE语句并指定表类型为EXTERNAL,使用LOAD DATA语句并将dividends.csv文件加载到dividends_unpartitioned表中。
8. 实验问题:Hive无法启动并且运行时出现错误。
解决方法:检查Hive的配置文件,确保所有的配置参数都正确设置,同时确保Hadoop集群正常运行。
9. 实验问题:Hive查询执行速度较慢。
解决方法:优化Hive的查询语句或者通过添加索引、分区、压缩等方式提高查询性能。
10. 实验问题:Hive无法访问HDFS文件。
解决方法:检查Hive和Hadoop的配置,确保Hive可以正确访问Hadoop集群中的文件。
11. 实验问题:Hive无法处理大文件。
解决方法:调整Hive的配置参数,如设置最大文件大小、调整内存设置等,以处理大文件。
12. 实验问题:Hive查询结果不正确。
解决方法:检查查询语句和数据,确保查询语句正确,数据格式正确。
13. 实验问题:Hive无法处理NULL值。
解决方法:在查询语句中正确处理NULL值,例如使用COALESCE函数或IFNULL函数。
14. 实验问题:Hive无法处理非数字类型的字段。
解决方法:将非数字类型的字段转换为数字类型,或者在查询中使用适当的函数处理这些字段。
15. 实验问题:Hive无法进行复杂的数据处理。
解决方法:使用更高级的Hive功能,如自定义函数、视图、表等,以进行更复杂的数据处理。
16. 实验问题:在查询数据时,出现查询速度慢的问题。
解决方法:优化查询语句,尽量减少全表扫描的情况,可以使用过滤器或者二级索引来提高查询效率。
17. 实验问题:Hive无法进行跨表查询。
解决方法:创建适当的索引和视图,以支持跨表查询。
18. 实验问题:Hive查询返回结果为空。
解决方法:检查查询语句和表是否存在问题,确认查询条件是否正确。如果查询语句正确但结果仍为空,可以尝试检查表中是否存在数据或是否存在NULL值。
19. 实验问题:Hive查询时出现异常错误。
解决方法:检查查询语句和表是否存在问题,确认查询条件是否正确,如果查询语句正确但结果仍异常错误,可以尝试检查Hadoop集群是否存在问题。
20. 实验问题:Hive无法处理复杂的数据类型。
解决方法:使用Hive的高级特性,如自定义函数、视图、表等,以处理复杂的数据类型,同时将复杂的数据类型转换为简单类型进行处理。
五、心得体会
1、通过这次实验,我深入了解了Hive表的概念和分类,包括内部表和外部表,以及它们各自的适用场景,这让我对Hive的数据存储和处理有了更全面的认识。
2、在创建Hive表时,选择合适的字段分隔符非常重要,我选择了英文逗号作为字段分隔符,这样可以确保数据导入的准确性以及在创建外部分区表时,设置合适的分区字段也可以提高查询效率。
3、通过从CSV文件中导入数据到Hive表中,我掌握了数据导入的基本方法,还学习了如何使用LOADDATA语句来实现高效的数据导入。
4、在创建未分区的外部表时,我意识到未分区表可能会在查询时面临性能问题,因此在实际应用中,应该根据数据规模和查询需求来选择合适的表类型。
5、通过将数据从未分区表导入到分区表中,我体验到了Hive自动分区特性的便利,这样可以避免手动创建大量分区,提高数据管理的效率。
6、在查询数据时,使用WHERE子句和相关字段的筛选条件来获取符合条件的数据记录,此外使用GROUP BY子句和聚合函数来进行数据分类和聚合操作。
7、通过查询IBM公司的数据,我掌握了如何使用Hive查询语句来获取特定公司的交易信息,让我对Hive查询在实际应用中的适用性有了更深刻的认识。
8、在查询苹果公司的涨跌情况时,我使用了CASE语句来根据涨跌情况对数据进行分类,使用CASE语句可以非常方便地进行数据转换和分类操作。
9、通过查询stocks表中的数据,我掌握了条件筛选、排序、限制等操作在Hive查询中的应用技巧,有助于我在未来的数据处理和分析工作中更加高效和准确地完成任务。