> 數據加載
數據準備:
在本地先創建兩個txt文件:
mahao@ubuntu:~$ cat user.txt
1,zhangsan
2,lisi
3,wangwu
mahao@ubuntu:~$ cat job.txt
1 工程師 1
2 美工
3 美工 4
創建users表
hive> CREATE TABLE IF NOT EXISTS users(id INT,name STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/tmp/testtable/user';
OK
Time taken: 2.726 seconds
如果hdfs文件系統中沒有/tmp/testtable/user這個文件,就會自動創建。
創建job表
hive> CREATE TABLE IF NOT EXISTS job(id INT,job STRING,user_id INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/tmp/testtable/job';
OK
Time taken: 0.164 seconds
如果hdfs文件系統中沒有/tmp/testtable/job這個文件,就會自動創建。
此時,如果hdfs文件系統中沒有這兩個目錄,那麼已經創建好了:
mahao@ubuntu:~$ hadoop fs -ls /tmp/testtable
Found 2 items
drwx-wx-wx - mahao supergroup 0 2016-09-13 02:06 /tmp/testtable/job
drwx-wx-wx - mahao supergroup 0 2016-09-13 02:05 /tmp/testtable/user
管理表(內部表)Load數據有3種:
1、
LOAD DATA [LOCAL] INPATH 'file_path' [OVERWRITE] INTO TABLE table_name
如:
LOAD DATA LOCAL INPATH '/home/mahao/use.txt' OVERWRITE INTO TABLE users;
2、
hdfs fs -put ***
如:
hdfs fs -puy /home/mahao/user.txt /tmp/testtable/user
3、從其他表中加載
如:
INSERT OVERWRITE TABLE employees
PARTITION (country='US',state='OR')
SELECT * FROM staged_employees se WHERE se.cnty='US' AND se.st='OR';
這裏我們選擇第一種方式:
hive> LOAD DATA LOCAL INPATH '/home/mahao/user.txt' OVERWRITE INTO TABLE users;
Loading data to table default.users
OK
Time taken: 0.534 seconds
然後會發現hdfs文件系統下的/tmp/testtable/user目錄下多了一個user.txt文件:
mahao@ubuntu:~$ hadoop fs -ls /tmp/testtable/user
Found 1 items
-rwx-wx-wx 1 mahao supergroup 27 2016-09-13 05:31 /tmp/testtable/user/user.txt
此時查看users表:
hive> SELECT * FROM users;
OK
1 zhangsan
2 lisi
3 wangwu
Time taken: 0.503 seconds, Fetched: 3 row(s)
成功將/home/mahao/user.txt文件中的數據導入users表。
爲了演示,我們採用第二種方式加載job表。
mahao@ubuntu:~$ hadoop fs -put /home/mahao/job.txt /tmp/testtable/job
mahao@ubuntu:~$ hadoop fs -ls /tmp/testtable/job
Found 1 items
-rw-r--r-- 1 mahao supergroup 35 2016-09-13 05:44 /tmp/testtable/job/job.txt
查看job表:
hive> select * from job;
OK
1 工程師 1
2 美工 NULL
3 美工 4
Time taken: 0.118 seconds, Fetched: 3 row(s)
> JOIN
INNER JOIN
只有進行連接的兩個表中都存在與連接標準相匹配的數據纔會被保留下來。
hive>SELECT * FROM users JOIN job ON users.id=job.user_id;
結果:
id name id job user_id
1 zhangsan 1 工程師 1
2 lisi 2 美工 2
OUTER JOIN
OUTER JOIN包括LEFT OUTER JOIN和RIGHT OUTER JOIN。
LEFT OUTER JOIN:
包括左邊表中的所有符合WHERE語句的記錄,甚至是右邊表中沒有和它匹配的記錄。右表中沒有匹配的記錄時,字段爲NULL。
hive>SELECT * FROM users LEFT OUTER JOIN job ON users.id=job.user_id;
結果:
1 zhangsan 1 工程師 1
2 lisi 2 美工 2
3 wangwu NULL NULL NULL
RIGHT OUTER JOIN:
包括右邊表中的所有符合WHERE語句的記錄,甚至是作左邊表中沒有和它匹配的記錄。左表中沒有匹配的記錄時,字段爲NULL。
hive>SELECT * FROM users RIGHT OUTER JOIN job ON users.id=job.user_id;
結果:
1 zhangsan 1 工程師 1
2 lisi 2 美工 2
NULL NULL 3 美工 4
FULL OUTER JOIN:
包括左邊表和右邊表的所有符合WHERE語句的記錄,沒有匹配的字段爲NULL。
hive>SELECT * FROM users FULL OUTER JOIN job ON users.id=job.user_id;
結果:
1 zhangsan 1 工程師 1
2 lisi 2 美工 2
3 wangwu NULL NULL NULL
NULL NULL 3 美工 4
LEFT SEMI JOIN(左半開連接):
返回左表users的記錄,這些記錄的id在右表job的user_id中出現:
hive> SELECT * FROM users LEFT SEMI JOIN job ON users.id=job.user_id;
結果:
1 zhangsan
2 lisi
該語句相當於SQL的如下語句
select * from user where id in (select user_id from job);
但是,hive不支持in子句。所以只能變通,使用LEFT SEMI JOIN子句。
笛卡爾積JOIN
表示左邊表的行數乘以右邊表的行數等於笛卡爾積的大小。
hive> SELECT * FROM users join job;
結果:
1 zhangsan 1 工程師 1
2 lisi 1 工程師 1
3 wangwu 1 工程師 1
1 zhangsan 2 美工 2
2 lisi 2 美工 2
3 wangwu 2 美工 2
1 zhangsan 3 美工 4
2 lisi 3 美工 4
3 wangwu 3 美工 4
map-side JOIN
如果所有表中只有一個小表,那麼可以在最大的表通過mapper時將小表完全放到內存中。在內存中,可以和小表進行逐一匹配。
開啓這個功能,需要:
hive>set hive.auto.covert.join=true;
然後在必要的時候Hive會啓動這個優化。
hive>SELECT * FROM ta join tb on ta.id=tb.id AND ta.ymd=tb.ymd
可以設置能夠使用這個優化的小表的大小:
hive>set hive.mapjoin.smalltable.filesize=25000000
大小是字節。