一臉懵逼學習Hive的使用以及常用語法(Hive語法即Hql語法)


Hive官網(HQL)語法手冊(英文版):https://cwiki.apache.org/confluence/display/Hive/LanguageManual

 Hive的數據存儲

  1、Hive中所有的數據都存儲在 HDFS 中,沒有專門的數據存儲格式(可支持Text,SequenceFile,ParquetFile,RCFILE等)

  2、只需要在創建表的時候告訴 Hive 數據中的列分隔符和行分隔符,Hive 就可以解析數據。

  3、Hive 中包含以下數據模型:DB、Table,External Table,Partition,Bucket。

       (1):db:在hdfs中表現為${hive.metastore.warehouse.dir}目錄下一個文件夾

    (2):table:在hdfs中表現所屬db目錄下一個文件夾

    (3):external table:外部表, 與table類似,不過其數據存放位置可以在任意指定路徑

        普通表: 刪除表后, hdfs上的文件都刪了

        External外部表刪除后, hdfs上的文件沒有刪除, 只是把文件刪除了

    (4): partition:在hdfs中表現為table目錄下的子目錄

    (5):bucket:桶, 在hdfs中表現為同一個表目錄下根據hash散列之后的多個文件, 會根據不同的文件把數據放到不同的文件中

hive創建數據庫操作:

hive提供database的定義,database的主要作用是提供數據分割的作用,方便數據關閉,命令如下所示:
#創建:
create (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES] (property_name=value,name=value...)

#顯示描述信息:
describe DATABASE|SCHEMA [extended] database_name。

#刪除:
DROP DATABASE|SHCEMA [IF EXISTS] database_Name [RESTRICT|CASCADE]

#使用:
user database_name;

 1:Hive創建數據表:

 (1)創建表(DDL操作)

建表語法如下所示:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

   [(col_name data_type [COMMENT col_comment], ...)]  ----指定表的名稱和表的具體列信息。

   [COMMENT table_comment]  ---表的描述信息。

   [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]  ---表的分區信息。

   [CLUSTERED BY (col_name, col_name, ...) 

   [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]   ---表的桶信息。

   [ROW FORMAT row_format]  ---表的數據分割信息,格式化信息。

   [STORED AS file_format]   ---表數據的存儲序列化信息。

   [LOCATION hdfs_path]  ---數據存儲的文件夾地址信息。

創建數據表解釋說明:

1、 CREATE TABLE 創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用 IF NOT EXISTS 選項來忽略這個異常。hive中的表可以分為內部表(托管表)和外部表,區別在於,外部表的數據不是有hive進行管理的,也就是說當刪除外部表的時候,外部表的數據不會從hdfs中刪除。而內部表是由hive進行管理的,在刪除表的時候,數據也會刪除。一般情況下,我們在創建外部表的時候會將表數據的存儲路徑定義在hive的數據倉庫路徑之外。hive創建表主要有三種方式,第一種直接使用create table命令,第二種使用create table ... as select...(會產生數據)。第三種使用create table tablename like exist_tablename命令。

2、 EXTERNAL關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION),Hive 創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。

3、 LIKE 允許用戶復制現有的表結構,但是不復制數據。

4、 ROW FORMAT

DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]

        [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

   | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶還需要為表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe,Hive通過 SerDe 確定表的具體的列的數據。

5、 STORED AS

SEQUENCEFILE  |  TEXTFILE  RCFILE

如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,使用 STORED AS SEQUENCEFILE

 6、CLUSTERED BY

對於每一個表(table)或者分區, Hive可以進一步組織成桶,也就是說桶是更為細粒度的數據范圍划分。Hive也是 針對某一列進行桶的組織。Hive采用對列值哈希,然后除以桶的個數求余的方式決定該條記錄存放在哪個桶當中。

把表(或者分區)組織成桶(Bucket)有兩個理由:

(1)獲得更高的查詢處理效率。桶為表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,連接兩個在(包含連接列的)相同列上划分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現。比如JOIN操作。對於JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那么將保存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的數據量。

(2)使取樣(sampling)更高效。在處理大規模數據集時,在開發和修改查詢的階段,如果能在數據集的一小部分數據上試運行查詢,會帶來很多方便。

7、create table命令介紹2

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name] table_name LIKE existing_table_orview_name ---指定要創建的表和已經存在的表或者視圖的名稱。

[LOCATION hdfs_path] ---數據文件存儲的hdfs文件地址信息。

8、CREATE [EXTERNAL] TABLE [IF NOT EXISTS]

[db_Name] table_name ---指定要創建的表名稱

...指定partition&bucket等信息,指定數據分割符號。

[AS select_statement] ---導入的數據

CREATE TABLE page_view(viewTime INT, userid BIGINT,
     page_url STRING, referrer_url STRING,
     ip STRING COMMENT 'IP Address of the User')
 COMMENT 'This is the page view table'
 PARTITIONED BY(dt STRING, country STRING)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\t'
STORED AS SEQUENCEFILE;

 創建數據表解釋如下所示:

# page_view是數據表的名稱,注意hive的數據類型和java的數據類型類似,和mysql和oracle等數據庫的字段類型不一致。
CREATE TABLE page_view(viewTime INT, userid BIGINT,
     page_url STRING, referrer_url STRING,
     ip STRING COMMENT 'IP Address of the User')

#COMMENT描述,可有可無的。
 COMMENT 'This is the page view table'

# PARTITIONED BY指定表的分區,可以先不管。
 PARTITIONED BY(dt STRING, country STRING)

# ROW FORMAT DELIMITED代表一行是一條記錄,是自己創建的全部字段和文件的字段對應,一行對應一條記錄。
 ROW FORMAT DELIMITED

#FIELDS TERMINATED BY '\001'代表一行記錄中的各個字段以什么隔開,方便創建的數據字段對應文件的一條記錄的字段。
   FIELDS TERMINATED BY '\001'

# STORED AS SEQUENCEFILE;代表對應的文件類型。最常見的是SEQUENCEFILE(以鍵值對類型格式存儲的)類型。TEXTFILE類型。
STORED AS SEQUENCEFILE;

創建如下所示,之前創建的不符合規范,刪除了,然后創建一個標准的,查看一下,最后一個指定類型的,可以不指定,默認就是普通的文本類型的:

 

 Hive將創建的數據類型寫到元數據庫,可以使用本地Navicat連接虛擬機的mysql查看數據;可是呢,出現下面的情況,百度唄,解決方法一大推,我貼一下子的解決方法:

錯誤(貼出來,方便被搜索到,哈哈哈哈。):1130 -Host '192.168.3.132' is not allowed to connect to this MySQL server

 百度方法很多,但是不是每一個都適合你,我就百度了很多沒解決我的問題,所以我還是貼一下我的解決方法:

如何開啟MySQL的遠程帳號(Navicat遠程連接自己的mysql數據庫):

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

再執行下面的語句,方可立即生效(修改的權限即時生效)。
mysql> FLUSH PRIVILEGES;

上面的語句表示將 所有的 數據庫的所有權限授權給 root 這個用戶,允許 root 用戶在 192.168.3.132 這個 IP 進行遠程登陸,並設置 root 用戶的密碼為 123456 。

下面逐一分析所有的參數:

(1)all PRIVILEGES 表示賦予所有的權限給指定用戶,這里也可以替換為賦予某一具體的權限,例如select,insert,update,delete,create,drop 等,具體權限間用“,”半角逗號分隔。

(2)*.* 表示上面的權限是針對於哪個表的,*指的是所有數據庫,后面的 * 表示對於所有的表,由此可以推理出:對於全部數據庫的全部表授權為“*.*”,對於某一數據庫的全部表授權為“數據庫名.*”,對於某一數據庫的某一表授權為“數據庫名.表名”。

(3)root 表示你要給哪個用戶授權,這個用戶可以是存在的用戶,也可以是不存在的用戶。

(4)192.168.3.132   表示允許遠程連接的 IP 地址,如果想不限制鏈接的 IP 則設置為“%”即可。

(5)123456 為用戶的密碼。

 可以使用Navicat工具查看一下自己的創建的數據表(tabs是保存了創建了那些表名):

 可以看看自己創建了那些列(在COLUMNS_V2數據表里面):

 可以看到有DBS里面保存了哪些數據庫:

 DBS數據表的DB_LOCATION_URI字段保存了路徑:hdfs://ns1/user/hive/warehouse

可以去hdfs里看一眼,里面確實保存着數據庫(突然發現有點意思了,只可意會,言傳不了了,哈哈哈哈~~~~):

 2:創建好數據表,了解了一些基本知識以后,開始插入數據,了解更多的知識:

//create & load(創建好數據表以后導入數據的操作如):
hive> create table tb_order(id int,name string,memory string,price double)
    > row format delimited
    > fields terminated by '\t';
    
//從本地導入數據到hive的表中(實質就是將文件上傳到hdfs中hive管理目錄下)
load data local inpath '/home/hadoop/ip.txt' into table 要導入的表名稱;

//從hdfs上導入數據到hive表中(實質就是將文件從原始目錄移動到hive管理的目錄下)
load data inpath 'hdfs://ns1/aa/bb/data.log' into table 要導入的表名稱;

 

//使用select語句來批量插入數據
insert overwrite table tab_ip_seq select * from 要導入的表名稱;

自己造一組數據,保存一下,如我的,在/home/hadoop/目錄下面phoneorder.data,內容如下所示:

[root@slaver3 hadoop]# vim phoneorder.data

想了一下,由於學習hive,會有很多測試數據,自己創建一個hivetest目錄,專一用於存放hive測試數據,如下所示:

10010    小米1    2G    1999
10011    小米2    4G    1999
10012    小米3    4G    1999
10013    小米4    6G    2999
10014    小米5    6G    2999
10015    小米6    8G    2999
10016    小米7    8G    3999

 然后開始導入數據(或者使用hadoop的命令將正確格式數據上傳到對應的目錄),如下所示:

hive> load data local inpath '/home/hadoop/hivetest/phoneorder.data' into table tb_order;

或者[root@slaver3 hivetest]# hadoop fs -put phoneorder2.data /user/hive/warehouse/tb_order

 

 可以去hdfs看到數據已經上傳成功了,如下所示,可以看到一些簡單信息:

下面可以使用hive的查詢語句進行查詢操作;

 3:Hive的查詢語句進行查詢操作,統計多少條記錄的時候發現很慢很慢,那是啟動集群的時候就很慢,最后可以看到一共7條記錄,用了一百多秒:

 

 4:external外部表,優點,做數據分析的時候,有的數據是業務系統產生的,或者讀或者寫這個文件,如果的默認的路徑,即在配置文件里面寫好了,如果做分析的時候數據表導數據,如果將數據表移動了,,業務系統再讀這個文件就不存在了,這個時候使用外部表,外部表不要求數據非到默認的路徑下面去,數據可以擺放到任意的hdfs路徑下面;

創建外部表的語法:

//external外部表
CREATE EXTERNAL TABLE tab_ip_ext(id int, name string,
     ip STRING,
     country STRING)
 ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
 STORED AS TEXTFILE
 LOCATION '/external/user';
//external外部表
//使用關鍵字EXTERNAL 
CREATE EXTERNAL TABLE 數據表名稱(id int, name string,
     ip STRING,
     country STRING)
 ROW FORMAT DELIMITED 
 FIELDS TERMINATED BY '\t'
 STORED AS TEXTFILE

#location指定所在的位置:切記,重點。
 LOCATION '/external/user';

 然后自己創建一個文件在hdfs,上傳一個文件,然后創建一個擴展表和這個hdfs的文件關聯起來:

[root@slaver3 hadoop]# cd /home/hadoop/hivetest/
[root@slaver3 hivetest]# cp phoneorder.data phoneorder4.data

[root@slaver3 hivetest]# hadoop fs -mkdir /hive_ext
[root@slaver3 hivetest]# hadoop fs -put phoneorder4.data /hive_ext

然后創建一個擴展表和這個hdfs的文件關聯起來:

hive> create external table tb_order_ext(id int,name string,memory string,price double)
    > row format delimited
    > fields terminated by '\t'
    > location '/hive_ext';

 具體操作如下所示:

 

查看一下是否存在數據:

 

可以查看擴展數據表的數據表結構,如下所示:

1 hive> desc extended tb_log;
2 OK
3 logid                   int                                         
4 logname                 string                                      
5           
6 Detailed Table Information    Table(tableName:tb_log, dbName:test, owner:root, createTime:1512892171, lastAccessTime:0, retention:0, sd:StorageDescriptor(cols:[FieldSchema(name:logid, type:int, comment:null), FieldSchema(name:logname, type:string, comment:null)], location:hdfs://master:9000/tb_log_file, inputFormat:org.apache.hadoop.mapred.TextInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, parameters:{serialization.format=,, field.delim=,}), bucketCols:[], sortCols:[], parameters:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[], parameters:{EXTERNAL=TRUE, transient_lastDdlTime=1512892171}, viewOriginalText:null, viewExpandedText:null, tableType:EXTERNAL_TABLE)    
7 Time taken: 0.121 seconds, Fetched: 4 row(s)
8 hive> 

 格式化查看擴展表的數據表結構:

 1 hive> desc formatted tb_log;
 2 OK
 3 # col_name                data_type               comment             
 4           
 5 logid                   int                                         
 6 logname                 string                                      
 7           
 8 # Detailed Table Information          
 9 Database:               test                     
10 Owner:                  root                     
11 CreateTime:             Sat Dec 09 23:49:31 PST 2017     
12 LastAccessTime:         UNKNOWN                  
13 Protect Mode:           None                     
14 Retention:              0                        
15 Location:               hdfs://master:9000/tb_log_file     
16 Table Type:             EXTERNAL_TABLE           
17 Table Parameters:          
18     EXTERNAL                TRUE                
19     transient_lastDdlTime    1512892171          
20           
21 # Storage Information          
22 SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe     
23 InputFormat:            org.apache.hadoop.mapred.TextInputFormat     
24 OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat     
25 Compressed:             No                       
26 Num Buckets:            -1                       
27 Bucket Columns:         []                       
28 Sort Columns:           []                       
29 Storage Desc Params:          
30     field.delim             ,                   
31     serialization.format    ,                   
32 Time taken: 0.577 seconds, Fetched: 29 row(s)
33 hive> 

 5:創建分區表(分區的好處是可以幫助你統計的時候少統計一些數據,加速數據統計):

hive> create table tb_part(sNo int,sName string,sAge int,sDept string)
    > partition //拿不准的單詞,可以tab一下進行提示,並不會影響你創建表;謝謝
partition     partitioned   partitions    
    > partitioned by (part string)
    > row format delimited  
    > fields terminated by ','
    > stored as textfile;
OK
Time taken: 0.351 seconds

 並且將本地的數據上傳到hive上面:

 1 hive> load data local inpath '/home/hadoop/data_hadoop/tb_part' overwrite into table tb_part partition (part='20171210');
 2 Loading data to table test.tb_part partition (part=20171210)
 3 Partition test.tb_part{part=20171210} stats: [numFiles=1, numRows=0, totalSize=43, rawDataSize=0]
 4 OK
 5 Time taken: 2.984 seconds
 6 hive> load data local inpath '/home/hadoop/data_hadoop/tb_part' overwrite into table tb_part partition (part='20171211');
 7 Loading data to table test.tb_part partition (part=20171211)
 8 Partition test.tb_part{part=20171211} stats: [numFiles=1, numRows=0, totalSize=43, rawDataSize=0]
 9 OK
10 Time taken: 0.566 seconds
11 hive> show par
12 parse_url(         parse_url_tuple(   partition          partitioned        partitions         
13 hive> show partition
14 partition     partitioned   partitions    
15 hive> show partitions tb_part;
16 OK
17 part=20171210
18 part=20171211
19 Time taken: 0.119 seconds, Fetched: 2 row(s)
20 hive> 

6:創建帶桶的數據表,然后將本地創建好測試數據上傳到hive上面:

#設置變量,設置分桶為true, 設置reduce數量是分桶的數量個數
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;

 1 hive> create table if not exists tb_stud(id int,name string,age int)
 2     > partitioned by(clus string)
 3     > clustered by(id) sorted by(age) into 2 buckets  #分桶,根據id進行分桶,分成2個桶。  4     > row format delimited 
 5     > fields terminated by ',';
 6 OK
 7 Time taken: 0.194 seconds
 8 hive> load data local inpath '/home/hadoop/data_hadoop/tb_clustered' overwrite into table tb_stud partition (clus='20171211');
 9 Loading data to table test.tb_stud partition (clus=20171211)
10 Partition test.tb_stud{clus=20171211} stats: [numFiles=1, numRows=0, totalSize=38, rawDataSize=0]
11 OK
12 Time taken: 0.594 seconds
13 hive> 

7:修改表,增加/刪除分區

語法結構
ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
partition_spec:
: PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)

ALTER TABLE table_name DROP partition_spec, partition_spec,...
具體實例如下所示:
alter table student_p add partition(part='a') partition(part='b');   

修改分區和刪除分區的操作:

hive> alter table tb_stud add partition(clus='20171215') location '/user/hive/warehouse/test.db' partition(clus='20171216');
OK
Time taken: 1.289 seconds
hive> alter table tb_stud add partition
partition     partitioned   partitions    
hive> alter table tb_stud add partition(clus='20171217');
OK
Time taken: 0.097 seconds
hive> dfs -ls /user/hive/warehouse/test.db
    > ;
Found 4 items
drwxr-xr-x   - root supergroup          0 2017-12-09 23:32 /user/hive/warehouse/test.db/tb_log
drwxr-xr-x   - root supergroup          0 2017-12-10 00:14 /user/hive/warehouse/test.db/tb_part
drwxr-xr-x   - root supergroup          0 2017-12-10 00:43 /user/hive/warehouse/test.db/tb_stud
drwxr-xr-x   - root supergroup          0 2017-12-09 21:28 /user/hive/warehouse/test.db/tb_user
hive> show partitions tb_stud;
OK
clus=20171211
clus=20171215
clus=20171216
clus=20171217
Time taken: 0.119 seconds, Fetched: 4 row(s)
hive> alter table tb_stud drop partition
partition     partitioned   partitions    
hive> alter table tb_stud drop partition(clus='20171217');
Dropped the partition clus=20171217
OK
Time taken: 1.433 seconds
hive> show partitions tb_stud;
OK
clus=20171211
clus=20171215
clus=20171216
Time taken: 0.092 seconds, Fetched: 3 row(s)
hive> alter table tb_stud drop partition(clus='20171215'),partition(clus='20171216');
Dropped the partition clus=20171215
Dropped the partition clus=20171216
OK
Time taken: 0.271 seconds
hive> show partitions tb_stud;
OK
clus=20171211
Time taken: 0.094 seconds, Fetched: 1 row(s)
hive> 

 8:重命名表:

語法結構
ALTER TABLE table_name RENAME TO new_table_name
具體實例 ,如下所示:

 1 hive> show tables;
 2 OK
 3 tb_log
 4 tb_part
 5 tb_stud
 6 tb_user
 7 Time taken: 0.026 seconds, Fetched: 4 row(s)
 8 hive> alter table tb_user rename to tb_user_copy;
 9 OK
10 Time taken: 0.19 seconds
11 hive> show tables;
12 OK
13 tb_log
14 tb_part
15 tb_stud
16 tb_user_copy
17 Time taken: 0.05 seconds, Fetched: 4 row(s)
18 hive> 

 9:增加/更新列

語法結構
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

注:ADD是代表新增一字段,字段位置在所有列后面(partition列前),REPLACE則是表示替換表中所有字段。

ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
具體實例如下所示:

 1 hive> desc tb_user;
 2 OK
 3 id                      int                                         
 4 name                    string                                      
 5 Time taken: 0.148 seconds, Fetched: 2 row(s)
 6 hive> alter table tb_user add columns(age int);
 7 OK
 8 Time taken: 0.238 seconds
 9 hive> desc tb_user;
10 OK
11 id                      int                                         
12 name                    string                                      
13 age                     int                                         
14 Time taken: 0.088 seconds, Fetched: 3 row(s)
15 hive> alter table tb_user replace columns(id int,name string,birthday string);
16 OK
17 Time taken: 0.132 seconds
18 hive> desc tb_user;
19 OK
20 id                      int                                         
21 name                    string                                      
22 birthday                string                                      
23 Time taken: 0.083 seconds, Fetched: 3 row(s)
24 hive> 

 10:Load,操作只是單純的復制/移動操作,DML操作

語法結構
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

說明:
1、Load 操作只是單純的復制/移動操作,將數據文件移動到 Hive 表對應的位置。
2、filepath:
  相對路徑,例如:project/data1
  絕對路徑,例如:/user/hive/project/data1
  包含模式的完整 URI,列如:
  hdfs://namenode:9000/user/hive/project/data1
3、LOCAL關鍵字
  如果指定了 LOCAL, load 命令會去查找本地文件系統中的 filepath。
  如果沒有指定 LOCAL 關鍵字,則根據inpath中的uri[如果指定了 LOCAL,那么:
  load 命令會去查找本地文件系統中的 filepath。如果發現是相對路徑,則路徑會被解釋為相對於當前用戶的當前路徑。
  load 命令會將 filepath中的文件復制到目標文件系統中。目標文件系統由表的位置屬性決定。被復制的數據文件移動到表的數據對應的位置。
 
  如果沒有指定 LOCAL 關鍵字,如果 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI。 否則:如果沒有指定   schema 或者 authority,Hive 會使用在 hadoop 配置文件中定義的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI。
  如果路徑不是絕對的,Hive 相對於/user/進行解釋。
  Hive 會將 filepath 中指定的文件內容移動到 table (或者 partition)所指定的路徑中。]查找文件

4、OVERWRITE 關鍵字
如果使用了 OVERWRITE 關鍵字,則目標表(或者分區)中的內容會被刪除,然后再將 filepath 指向的文件/目錄中的內容添加到表/分區中。
如果目標表(分區)已經有一個文件,並且文件名和 filepath 中的文件名沖突,那么現有的文件會被新文件所替代。

 11:Hive的insert操作:

Insert
將查詢結果插入Hive表
語法結構
  INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement

Multiple inserts:
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ...] select_statement2] ...

Dynamic partition inserts:
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement

  1 <!--基本模式插入。-->
  2 hive> load data local inpath '/home/hadoop/data_hadoop/tb_stud' overwrite into table tb_stud partition (clus='20171211');
  3 Loading data to table test.tb_stud partition (clus=20171211)
  4 Partition test.tb_stud{clus=20171211} stats: [numFiles=1, numRows=0, totalSize=43, rawDataSize=0]
  5 OK
  6 Time taken: 4.336 seconds
  7 hive> select * from tb_stud where clus='20171211';
  8 OK
  9 1    張三    NULL    20171211
 10 2    lisi    NULL    20171211
 11 3    wangwu    NULL    20171211
 12 4    zhaoliu    NULL    20171211
 13 5    libai    NULL    20171211
 14 Time taken: 0.258 seconds, Fetched: 5 row(s)
 15 hive> insert overwrite table tb_stud partition(clus='20171218')
 16     >  select id,name,age from tb_stud where clus='20171211';
 17 Query ID = root_20171210012734_721f76d9-f670-42ad-bf68-bfb94baf5cda
 18 Total jobs = 3
 19 Launching Job 1 out of 3
 20 Number of reduce tasks is set to 0 since there's no reduce operator
 21 Starting Job = job_1512874725514_0005, Tracking URL = http://master:8088/proxy/application_1512874725514_0005/
 22 Kill Command = /home/hadoop/soft/hadoop-2.6.4/bin/hadoop job  -kill job_1512874725514_0005
 23 Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
 24 2017-12-10 01:28:00,125 Stage-1 map = 0%,  reduce = 0%
 25 2017-12-10 01:28:34,514 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.44 sec
 26 MapReduce Total cumulative CPU time: 1 seconds 440 msec
 27 Ended Job = job_1512874725514_0005
 28 Stage-4 is selected by condition resolver.
 29 Stage-3 is filtered out by condition resolver.
 30 Stage-5 is filtered out by condition resolver.
 31 Moving data to: hdfs://master:9000/user/hive/warehouse/test.db/tb_stud/clus=20171218/.hive-staging_hive_2017-12-10_01-27-34_894_112189266881641464-1/-ext-10000
 32 Loading data to table test.tb_stud partition (clus=20171218)
 33 Partition test.tb_stud{clus=20171218} stats: [numFiles=1, numRows=5, totalSize=58, rawDataSize=53]
 34 MapReduce Jobs Launched: 
 35 Stage-Stage-1: Map: 1   Cumulative CPU: 1.44 sec   HDFS Read: 3816 HDFS Write: 140 SUCCESS
 36 Total MapReduce CPU Time Spent: 1 seconds 440 msec
 37 OK
 38 Time taken: 64.66 seconds
 39 hive> select * from tb_stud where clus='20171218';
 40 OK
 41 1    張三    NULL    20171218
 42 2    lisi    NULL    20171218
 43 3    wangwu    NULL    20171218
 44 4    zhaoliu    NULL    20171218
 45 5    libai    NULL    20171218
 46 Time taken: 0.085 seconds, Fetched: 5 row(s)
 47 hive> 
 48 
 49 <!--多插入模式。-->
 50 hive> show partitions tb_stud;
 51 OK
 52 clus=20171211
 53 clus=20171218
 54 Time taken: 0.153 seconds, Fetched: 2 row(s)
 55 hive> alter table tb_stud add partition(clus='20171212');
 56 OK
 57 Time taken: 0.143 seconds
 58 hive> alter table tb_stud add partition(clus='20171213');
 59 OK
 60 Time taken: 0.399 seconds
 61 hive> alter table tb_stud add partition(clus='20171214');
 62 OK
 63 Time taken: 0.139 seconds
 64 hive> from tb_stud
 65     > insert overwrite table tb_stud partition(clus='20171213')
 66     > select id,name,age  where clus='20171211'
 67     > insert overwrite table tb_stud partition(clus='20171214')
 68     > select id,name,age  where clus='20171211';
 69 Query ID = root_20171210013655_0c4a1d78-88e2-4de0-99ca-074c9eed81a4
 70 Total jobs = 5
 71 Launching Job 1 out of 5
 72 Number of reduce tasks is set to 0 since there's no reduce operator
 73 Starting Job = job_1512874725514_0007, Tracking URL = http://master:8088/proxy/application_1512874725514_0007/
 74 Kill Command = /home/hadoop/soft/hadoop-2.6.4/bin/hadoop job  -kill job_1512874725514_0007
 75 Hadoop job information for Stage-2: number of mappers: 1; number of reducers: 0
 76 2017-12-10 01:37:05,501 Stage-2 map = 0%,  reduce = 0%
 77 2017-12-10 01:38:06,089 Stage-2 map = 0%,  reduce = 0%
 78 2017-12-10 01:38:08,363 Stage-2 map = 100%,  reduce = 0%, Cumulative CPU 1.46 sec
 79 MapReduce Total cumulative CPU time: 1 seconds 460 msec
 80 Ended Job = job_1512874725514_0007
 81 Stage-5 is selected by condition resolver.
 82 Stage-4 is filtered out by condition resolver.
 83 Stage-6 is filtered out by condition resolver.
 84 Stage-11 is selected by condition resolver.
 85 Stage-10 is filtered out by condition resolver.
 86 Stage-12 is filtered out by condition resolver.
 87 Moving data to: hdfs://master:9000/user/hive/warehouse/test.db/tb_stud/clus=20171213/.hive-staging_hive_2017-12-10_01-36-55_602_8039889333976698612-1/-ext-10000
 88 Moving data to: hdfs://master:9000/user/hive/warehouse/test.db/tb_stud/clus=20171214/.hive-staging_hive_2017-12-10_01-36-55_602_8039889333976698612-1/-ext-10002
 89 Loading data to table test.tb_stud partition (clus=20171213)
 90 Loading data to table test.tb_stud partition (clus=20171214)
 91 Partition test.tb_stud{clus=20171213} stats: [numFiles=1, numRows=0, totalSize=58, rawDataSize=0]
 92 Partition test.tb_stud{clus=20171214} stats: [numFiles=1, numRows=0, totalSize=58, rawDataSize=0]
 93 MapReduce Jobs Launched: 
 94 Stage-Stage-2: Map: 1   Cumulative CPU: 1.57 sec   HDFS Read: 4798 HDFS Write: 280 SUCCESS
 95 Total MapReduce CPU Time Spent: 1 seconds 570 msec
 96 OK
 97 Time taken: 81.536 seconds
 98 hive> select * from tb_stud where clus='20171213';
 99 OK
100 1    張三    NULL    20171213
101 2    lisi    NULL    20171213
102 3    wangwu    NULL    20171213
103 4    zhaoliu    NULL    20171213
104 5    libai    NULL    20171213
105 Time taken: 0.138 seconds, Fetched: 5 row(s)
106 hive> select * from tb_stud where clus='20171214';
107 OK
108 1    張三    NULL    20171214
109 2    lisi    NULL    20171214
110 3    wangwu    NULL    20171214
111 4    zhaoliu    NULL    20171214
112 5    libai    NULL    20171214
113 Time taken: 0.075 seconds, Fetched: 5 row(s)
114 hive> 
115 
116 <!--自動分區模式。-->

12:導出表數據

語法結構
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...

multiple inserts:
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...

具體實例

 1 1、導出文件到本地。
 2 說明:
 3 數據寫入到文件系統時進行文本序列化,且每列用^A來區分,\n為換行符。用more命令查看時不容易看出分割符,可以使用: sed -e 's/\x01/|/g' filename[]來查看。
 4 
 5 
 6 hive> insert overwrite local directory '/home/hadoop/data_hadoop/get_tb_stud'
 7     > select * from tb_stud;
 8 Query ID = root_20171210014640_4c499323-760e-4494-946b-5ffad8fb3789
 9 Total jobs = 1
10 Launching Job 1 out of 1
11 Number of reduce tasks is set to 0 since there's no reduce operator
12 Starting Job = job_1512874725514_0008, Tracking URL = http://master:8088/proxy/application_1512874725514_0008/
13 Kill Command = /home/hadoop/soft/hadoop-2.6.4/bin/hadoop job  -kill job_1512874725514_0008
14 Hadoop job information for Stage-1: number of mappers: 2; number of reducers: 0
15 2017-12-10 01:46:50,400 Stage-1 map = 0%,  reduce = 0%
16 2017-12-10 01:47:25,696 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 7.13 sec
17 MapReduce Total cumulative CPU time: 7 seconds 130 msec
18 Ended Job = job_1512874725514_0008
19 Copying data to local directory /home/hadoop/data_hadoop/get_tb_stud
20 Copying data to local directory /home/hadoop/data_hadoop/get_tb_stud
21 MapReduce Jobs Launched:
22 Stage-Stage-1: Map: 2   Cumulative CPU: 7.13 sec   HDFS Read: 10392 HDFS Write: 515 SUCCESS
23 Total MapReduce CPU Time Spent: 7 seconds 130 msec
24 OK
25 Time taken: 47.258 seconds
26 hive>
27 
28 <!--導出數據到HDFS。-->
29 hive> insert overwrite directory 'hdfs://192.168.199.130:9000/user/hive/warehouse/tb_stud_get'
30     > select * from tb_stud;
31 Query ID = root_20171210015229_b0a323b1-b1dc-4f31-b932-cb8126bac2ff
32 Total jobs = 3
33 Launching Job 1 out of 3
34 Number of reduce tasks is set to 0 since there's no reduce operator
35 Starting Job = job_1512874725514_0009, Tracking URL = http://master:8088/proxy/application_1512874725514_0009/
36 Kill Command = /home/hadoop/soft/hadoop-2.6.4/bin/hadoop job  -kill job_1512874725514_0009
37 Hadoop job information for Stage-1: number of mappers: 2; number of reducers: 0
38 2017-12-10 01:53:52,773 Stage-1 map = 0%,  reduce = 0%
39 2017-12-10 01:54:07,829 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 2.65 sec
40 MapReduce Total cumulative CPU time: 2 seconds 650 msec
41 Ended Job = job_1512874725514_0009
42 Stage-3 is filtered out by condition resolver.
43 Stage-2 is selected by condition resolver.
44 Stage-4 is filtered out by condition resolver.
45 Launching Job 3 out of 3
46 Number of reduce tasks is set to 0 since there's no reduce operator
47 Starting Job = job_1512874725514_0010, Tracking URL = http://master:8088/proxy/application_1512874725514_0010/
48 Kill Command = /home/hadoop/soft/hadoop-2.6.4/bin/hadoop job  -kill job_1512874725514_0010
49 Hadoop job information for Stage-2: number of mappers: 1; number of reducers: 0
50 2017-12-10 01:54:55,697 Stage-2 map = 0%,  reduce = 0%
51 2017-12-10 01:55:45,607 Stage-2 map = 100%,  reduce = 0%, Cumulative CPU 1.43 sec
52 MapReduce Total cumulative CPU time: 1 seconds 430 msec
53 Ended Job = job_1512874725514_0010
54 Moving data to: hdfs://192.168.199.130:9000/user/hive/warehouse/tb_stud_get
55 MapReduce Jobs Launched: 
56 Stage-Stage-1: Map: 2   Cumulative CPU: 2.65 sec   HDFS Read: 10412 HDFS Write: 515 SUCCESS
57 Stage-Stage-2: Map: 1   Cumulative CPU: 1.43 sec   HDFS Read: 2313 HDFS Write: 515 SUCCESS
58 Total MapReduce CPU Time Spent: 4 seconds 80 msec
59 OK
60 Time taken: 202.508 seconds
61 hive> dfs -ls /user/hive/warehouse/tb_stud_get;
62 Found 1 items
63 -rwxr-xr-x   2 root supergroup        515 2017-12-10 01:55 /user/hive/warehouse/tb_stud_get/000000_0
64 hive> 

13:SELECT,基本的Select操作

語法結構
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list [HAVING condition]]
[CLUSTER BY col_list
  | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
]
[LIMIT number]

注:1、order by 會對輸入做全局排序,因此只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。
2、sort by不是全局排序,其在數據進入reducer前完成排序。因此,如果用sort by進行排序,並且設置mapred.reduce.tasks>1,則sort by只保證每個reducer的輸出有序,不保證全局有序。
3、distribute by根據distribute by指定的內容將數據分到同一個reducer。
4、Cluster by 除了具有Distribute by的功能外,還會對該字段進行排序。因此,常常認為cluster by = distribute by + sort by

5、分桶表的最大的意思:最大的作用是用來提高join操作的效率;

6、思考這個問題:

 

  select a.id,a.name,b.addr from a join b on a.id = b.id;

 

  如果a表和b表已經是分桶表,而且分桶的字段是id字段

 

  做這個join操作時,還需要全表做笛卡爾積嗎?答案:不需要,因為相同的id就在同一個桶里面。

 

 14:刪除hive的內部表和外部表的區別:

  刪除內部表是將元數據(TABL表),以及hdfs上面的文件夾以及文件一起刪除;

  刪除外部表只是刪除元數據(TABL表),hdfs上面的文件夾以及文件不刪除。

 

15:創建一個新表根據老表(用來做一些中間結果的存儲,再做后一步的處理,):

注意:用於創建一些臨時表存儲中間結果

hive> create table tb_order_new  
    > as                         
    > select id,name,memory,price
    > from tb_order;  

16:insert from select   通過select語句批量插入數據到別的表(用於向臨時表中追加中間結果數據):

//創建一個表
create table tab_ip_like like tab_ip;

//批量插入數據,批量插入已經存在表
insert overwrite table tab_ip_like
    select * from tab_ip;
hive> create table tb_order_append(id int,name string,memory string,price double)
    > row format delimited
    > fields terminated by '\t';


hive> insert overwrite table tb_order_append
    > select * from tb_order;



hive> select * from tb_order_append;

操作如下所示:

17:PARTITION ,分區表(partition),分區統計,可以對數據操作加快速度:

查詢分區:hive> show partitions part;   #show partitions 數據表名稱;

刪除分區:hive> alter table part drop partition(date='20180512');

添加分區:hive> alter table part add partition(date='20180512');

hive> create table tb_order_part(id int,name string,memory string,salary double)
    > partitioned by (month string)                                             
    > row format delimited                                                      
    > fields terminated by '\t';                                                
OK
Time taken: 0.13 seconds

 然后將數據導入這個新建的分區里面(所謂分區就是在文件夾下面創建一個文件夾,把數據放到這個文件夾下面),如下所示:

hive> load data local inpath '/home/hadoop/hivetest/phoneorder.data' into table tb_order_part partition(month='201401');

hive> load data local inpath '/home/hadoop/hivetest/phoneorder2.data' into table tb_order_part partition(month='201402');

可以根據分區查詢一下數據:

18:write to hdfs,將結果寫入到hdfs的文件中:

hive> insert overwrite local directory '/home/hadoop/hivetest/test.txt' > select * from tb_order_part > where month="201401";

 19:Hive的Join使用:

語法結構 join_table: table_reference JOIN table_factor [join_condition] | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition | table_reference LEFT SEMI JOIN table_reference join_condition Hive 支持等值連接(equality joins)、外連接(outer joins)和(left/right joins)。Hive 不支持非等值的連接,因為非等值連接非常難轉化到 map/reduce 任務。 另外,Hive 支持多於 2 個表的連接。 寫 join 查詢時,需要注意幾個關鍵點: 1. 只支持等值join 例如: SELECT a.* FROM a JOIN b ON (a.id = b.id) SELECT a.* FROM a JOIN b ON (a.id = b.id AND a.department = b.department) 是正確的,然而: SELECT a.* FROM a JOIN b ON (a.id>b.id) 是錯誤的。 2. 可以 join 多於 2 個表。 例如 SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2) 如果join中多個表的 join key 是同一個,則 join 會被轉化為單個 map/reduce 任務,例如: SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1) 被轉化為單個 map/reduce 任務,因為 join 中只使用了 b.key1 作為 join key。 SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2) 而這一 join 被轉化為 2 個 map/reduce 任務。因為 b.key1 用於第一次 join 條件,而 b.key2 用於第二次 join。 3.join 時,每次 map/reduce 任務的邏輯: reducer 會緩存 join 序列中除了最后一個表的所有表的記錄,再通過最后一個表將結果序列化到文件系統。這一實現有助於在 reduce 端減少內存的使用量。實踐中,應該把最大的那個表寫在最后(否則會因為緩存浪費大量內存)。例如: SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1) 所有表都使用同一個 join key(使用 1 次 map/reduce 任務計算)。Reduce 端會緩存 a 表和 b 表的記錄,然后每次取得一個 c 表的記錄就計算一次 join 結果,類似的還有: SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2) 這里用了 2 次 map/reduce 任務。第一次緩存 a 表,用 b 表序列化;第二次緩存第一次 map/reduce 任務的結果,然后用 c 表序列化。 4.LEFT,RIGHT 和 FULL OUTER 關鍵字用於處理 join 中空記錄的情況 例如: SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) 對應所有 a 表中的記錄都有一條記錄輸出。輸出的結果應該是 a.val, b.val,當 a.key=b.key 時,而當 b.key 中找不到等值的 a.key 記錄時也會輸出: a.val, NULL 所以 a 表中的所有記錄都被保留了; “a RIGHT OUTER JOIN b”會保留所有 b 表的記錄。 Join 發生在 WHERE 子句之前。如果你想限制 join 的輸出,應該在 WHERE 子句中寫過濾條件——或是在 join 子句中寫。這里面一個容易混淆的問題是表分區的情況: SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) WHERE a.ds='2009-07-07' AND b.ds='2009-07-07' 會 join a 表到 b 表(OUTER JOIN),列出 a.val 和 b.val 的記錄。WHERE 從句中可以使用其他列作為過濾條件。但是,如前所述,如果 b 表中找不到對應 a 表的記錄,b 表的所有列都會列出 NULL,包括 ds 列。也就是說,join 會過濾 b 表中不能找到匹配 a 表 join key 的所有記錄。這樣的話,LEFT OUTER 就使得查詢結果與 WHERE 子句無關了。解決的辦法是在 OUTER JOIN 時使用以下語法: SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07') 這一查詢的結果是預先在 join 階段過濾過的,所以不會存在上述問題。這一邏輯也可以應用於 RIGHT 和 FULL 類型的 join 中。 Join 是不能交換位置的。無論是 LEFT 還是 RIGHT join,都是左連接的。 SELECT a.val1, a.val2, b.val, c.val FROM a JOIN b ON (a.key = b.key) LEFT OUTER JOIN c ON (a.key = c.key) 先 join a 表到 b 表,丟棄掉所有 join key 中不匹配的記錄,然后用這一中間結果和 c 表做 join。這一表述有一個不太明顯的問題,就是當一個 key 在 a 表和 c 表都存在,但是 b 表中不存在的時候:整個記錄在第一次 join,即 a JOIN b 的時候都被丟掉了(包括a.val1,a.val2和a.key),然后我們再和 c 表 join 的時候,如果 c.key 與 a.key 或 b.key 相等,就會得到這樣的結果:NULL, NULL, NULL, c.val

 長風破浪會有時,腰酸背痛頸椎疼。~~~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM