【注】該系列文章以及使用到安裝包/測試數據 可以在《傾情大奉送--Spark入門實戰系列》獲取
1、Hive操作演示
1.1 內部表
1.1.1 創建表並加載數據
第一步 啟動HDFS、YARN和Hive,啟動完畢后創建Hive數據庫
hive>create database hive;
hive>show databases;
hive>use hive;
第二步 創建內部表
由於Hive使用了類似SQL的語法,所以創建內部表的語句相對SQL只增加了行和字段分隔符。
hive>CREATE TABLE SOGOUQ2(DT STRING,WEBSESSION STRING,WORD STRING,S_SEQ INT,C_SEQ INT,WEBSITE STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' ;
第三步 加載數據
數據文件可以從HDFS或者本地操作系統加載到表中,如果加載HDFS文件使用LOAD DATA INPATH,而加載本地操作系統文件使用LOAD DATA LOCAL INPATH命令。HIVE表保存的默認路徑在${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir屬性指定,當創建表時會在hive.metastore.warehouse.dir指向的目錄下以表名創建一個文件夾,在本演示中表默認指向的是/user/hive/warehouse。
數據文件在本地操作系統將復制到表對應的目錄中,而數據文件在HDFS中,數據文件將移動到表對應的目錄中,原來的路徑將不存在該文件。在這里使用《Spark編程模型(上)--概念及Shell試驗》中在本地操作系統中的搜狗日志數據文件:
hive>LOAD DATA LOCAL INPATH '/home/hadoop/upload/sogou/SogouQ2.txt' INTO TABLE SOGOUQ2;
在/user/hive/warehouse/hive.db/sogouq2目錄下,可以看到SougouQ2.txt數據文件:
1.1.2 查詢行數
可以用count關鍵字查詢SogouQ2.txt數據行數,查詢時會啟動MapReduce進行計算,Map的個數一般和數據分片個數對應,在本查詢中有2個Map任務(數據文件有2個Block),1個Reduce任務。
hive>select count(*) from SOGOUQ2;
1.1.3 包含baidu的數據
可以用like關鍵字進行模糊查詢,Map的個數一般和數據分片個數對應。
hive>select count(*) from SOGOUQ2 where WEBSITE like '%baidu%';
1.1.4 查詢結果排名第1,點擊次序排第2,其中URL包含baidu的數據
hive>select count(*) from SOGOUQ2 where S_SEQ=1 and C_SEQ=2 and WEBSITE like '%baidu%';
1.2 外部表
1.2.1 創建表關聯數據
第一步 在HDFS創建外部表存放數據目錄
$hadoop fs -mkdir -p /class5/sogouq1
$hadoop fs -ls /class5
第二步 在Hive創建外部表,指定表存放目錄
hive>CREATE EXTERNAL TABLE SOGOUQ1(DT STRING,WEBSESSION STRING,WORD STRING,S_SEQ INT,C_SEQ INT,WEBSITE STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS TEXTFILE LOCATION '/class5/sogouq1';
hive>show tables;
觀察一下創建表和外部表的區別,會發現創建外部表多了EXTERNAL關鍵字以及指定了表對應存放文件夾LOCATION ‘/class5/sogouq1’
【注】在刪除表的時候,內部表將刪除表的元數據和數據文件;而刪除外部表的時候,僅僅刪除外部表的元數據,不刪除數據文件
第三步 加載數據文件到外部表對應的目錄中
創建Hive外部表關聯數據文件有兩種方式,一種是把外部表數據位置直接關聯到數據文件所在目錄上,這種方式適合數據文件已經在HDFS存在,另外一種方式是創建表時指定外部表數據目錄,隨后把數據加載到該目錄下。以下將以第二種方式進行演示:
$hadoop fs -copyFromLocal /home/hadoop/upload/sogou/SogouQ1.txt /class5/sogouq1/
$hadoop fs -ls /class5/sogouq1
$hadoop fs -tail /class5/sogouq1/SogouQ1.txt
1.2.2 查詢行數
hive>select count(*) from SOGOUQ1;
1.2.3 顯示前10行
hive>select * from SOGOUQ1 limit 10;
可以看出Hive會根據查詢不同任務決定是否生成Job,獲取前10條並沒有生成Job,而是得到數據后直接進行顯示。
1.2.4 查詢結果排名第1,點擊次序排第2的數據
hive>select count(*) from SOGOUQ1 where S_SEQ=1 and C_SEQ=2;
1.2.5 查詢次數排行榜
按照session號進行歸組,並按照查詢次數進行排序,最終顯示查詢次數最多的前10條。
hive>select WEBSESSION,count(WEBSESSION) as cw from SOGOUQ1 group by WEBSESSION order by cw desc limit 10;
2、交易數據演示
2.1 准備數據
2.1.1 上傳數據
交易數據存放在該系列配套資源的/class5/saledata目錄下,在/home/hadoop/upload創建class5目錄用於存放本周測試數據
$cd /home/hadoop/upload
$mkdir class5
創建新文件夾后使用,使用SSH Secure File Transfer工具上傳到/home/hadoop/upload/class5目錄下,如下圖所示:
2.1.2 在Hive創建數據庫和表
啟動Hadoop集群,進入Hive命令行操作界面,使用如下命令創建三張數據表:
l tbDate定義了日期的分類,將每天分別賦予所屬的月份、星期、季度等屬性,字段分別為日期、年月、年、月、日、周幾、第幾周、季度、旬、半月;
l tbStock定義了訂單表頭,字段分別為訂單號、交易位置、交易日期;
l tbStockDetail文件定義了訂單明細,該表和tbStock以交易號進行關聯,字段分別為訂單號、行號、貨品、數量、金額:
hive>use hive;
hive>CREATE TABLE tbDate(dateID string,theyearmonth string,theyear string,themonth string,thedate string,theweek string,theweeks string,thequot string,thetenday string,thehalfmonth string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' ;
hive>CREATE TABLE tbStock(ordernumber STRING,locationid string,dateID string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' ;
hive>CREATE TABLE tbStockDetail(ordernumber STRING,rownum int,itemid string,qty int,price int ,amount int) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' ;
2.1.3 導入數據
從本地操作系統分別加載日期、交易信息和交易詳細信息表數據
hive>use hive;
hive>LOAD DATA LOCAL INPATH '/home/hadoop/upload/class5/saledata/tbDate.txt' INTO TABLE tbDate;
hive>LOAD DATA LOCAL INPATH '/home/hadoop/upload/class5/saledata/tbStock.txt' INTO TABLE tbStock;
hive>LOAD DATA LOCAL INPATH '/home/hadoop/upload/class5/saledata/tbStockDetail.txt' INTO TABLE tbStockDetail;
查看HDFS中相關SALEDATA數據庫中增加了三個文件夾,分別對應三個表:
2.2 計算所有訂單每年的總金額
2.2.1 算法分析
要計算所有訂單每年的總金額,首先需要獲取所有訂單的訂單號、訂單日期和訂單金信息,然后把這些信息和日期表進行關聯,獲取年份信息,最后根據這四個列按年份歸組統計獲取所有訂單每年的總金額。
2.2.2 執行HSQL語句
hive>use hive;
hive>select c.theyear, sum(b.amount) from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and a.dateid=c.dateid group by c.theyear order by c.theyear;
運行過程中創建兩個Job,分別為job_1437659442092_0001和job_1437659442092_0002,運行過程如下:
在YARN的資源管理器界面中可以看到如下界面:
2.2.3 查看結果
整個計算過程使用了91.51秒,結果如下:
2.3 計算所有訂單每年最大金額訂單的銷售額
2.3.1 算法分析
該算法分為兩步:
1. 按照日期和訂單號進行歸組計算,獲取所有訂單每天的銷售數據;
2. 把第一步獲取的數據和日期表進行關聯獲取的年份信息,然后按照年份進行歸組,使用Max函數,獲取所有訂單每年最大金額訂單的銷售額。
2.3.2 執行HSQL語句
//所有訂單每年最大金額訂單的銷售額
//第一步:
hive>use hive;
hive>select a.dateid,a.ordernumber,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b where a.ordernumber=b.ordernumber group by a.dateid,a.ordernumber;
//第二步:
hive>select c.theyear,max(d.sumofamount) from tbDate c,(select a.dateid,a.ordernumber,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b where a.ordernumber=b.ordernumber group by a.dateid,a.ordernumber) d where c.dateid=d.dateid group by c.theyear sort by c.theyear;
運行過程中創建兩個Job,分別為job_1437659442092_0004和job_1437659442092_0005,運行過程如下:
在YARN的資源管理器界面中可以看到如下界面:
其中job_1437659442092_0005運行的具體情況如下:
2.3.3 查看結果
整個計算過程使用了285秒,結果如下:
2.4 計算其他金額
2.4.1 所有訂單中季度銷售額前10位
//所有訂單中季度銷售額前10位
hive>use hive;
hive>select c.theyear,c.thequot,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and a.dateid=c.dateid group by c.theyear,c.thequot order by sumofamount desc limit 10;
2008 1 5252819
2007 4 4613093
2007 1 4446088
2006 1 3916638
2008 2 3886470
2007 3 3870558
2007 2 3782235
2006 4 3691314
2005 1 3592007
2005 3 3304243
2.4.2 列出銷售金額在100000以上的單據
//列出銷售金額在100000以上的單據
hive>use hive;
hive>select a.ordernumber,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b where a.ordernumber=b.ordernumber group by a.ordernumber having sumofamount>100000;
2.4.3 所有訂單中每年最暢銷貨品
//所有訂單中每年最暢銷貨品
第一步:
hive>use hive;
hive>select c.theyear,b.itemid,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and
a.dateid=c.dateid group by c.theyear,b.itemid;
第二步:
hive>select d.theyear,max(d.sumofamount) as maxofamount from (select c.theyear,b.itemid,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and a.dateid=c.dateid group by c.theyear,b.itemid) d group by d.theyear ;
第三步:
hive>select distinct e.theyear,e.itemid,f.maxofamount from (select c.theyear,b.itemid,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and a.dateid=c.dateid group by c.theyear,b.itemid) e , (select d.theyear,max(d.sumofamount) as maxofamount from (select c.theyear,b.itemid,sum(b.amount) as sumofamount from tbStock a,tbStockDetail b,tbDate c where a.ordernumber=b.ordernumber and a.dateid=c.dateid group by c.theyear,b.itemid) d group by d.theyear) f where e.theyear=f.theyear and e.sumofamount=f.maxofamount order by e.theyear;
2004 JY424420810101 53374
2005 24124118880102 56569
2006 JY425468460101 113684
2007 JY425468460101 70226
2008 E2628204040101 97981
2009 YL327439080102 30029
2010 SQ429425090101 4494