1、什么是Hive
hive是基於hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張數據庫表
並提供類sql查詢功能
2、為什么要用Hive
1、直接使用hadoop所面臨的問題
人員學習成本太高
項目周期要求太短
MapReduce實現復雜查詢邏輯開發難度太大
2、為什么要使用Hive
操作接口采用類SQL語法,提供快速開發的能力。
避免了去寫MapReduce,減少開發人員的學習成本。
擴展功能很方便。
3、Hive的特點:可擴展,延展性,容錯
4、Hive的數據存儲
1、Hive中所有的數據都存儲在 HDFS 中,沒有專門的數據存儲格式(可支持Text,SequenceFile,ParquetFile,RCFILE等)
2、只需要在創建表的時候告訴 Hive 數據中的列分隔符和行分隔符,Hive 就可以解析數據。
3、Hive 中包含以下數據模型:DB、Table,External Table,Partition,Bucket。
# db:在hdfs中表現為${hive.metastore.warehouse.dir}目錄下一個文件夾
# table:在hdfs中表現所屬db目錄下一個文件夾
# external table:與table類似,不過其數據存放位置可以在任意指定路徑
# partition:在hdfs中表現為table目錄下的子目錄
# bucket:在hdfs中表現為同一個表目錄下根據hash散列之后的多個文件
5、使用方式:
啟動方式,(假如是在hadoop01上):
啟動為前台:bin/hiveserver2
啟動為后台:nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &
啟動成功后,可以在別的節點上用beeline去連接
方式(1)
hive/bin/beeline 回車,進入beeline的命令界面
輸入命令連接hiveserver2
beeline> !connect jdbc:hive2//mini1:10000
(hadoop01是hiveserver2所啟動的那台主機名,端口默認是10000)
方式(2)
或者啟動就連接:
bin/beeline -u jdbc:hive2://mini1:10000 -n hadoop
執行hive 的sql命令
[hadoop@hdp-node-02 ~]$ hive -e ‘sql’
3、HIVE基本操作
3.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 選項來忽略這個異常。
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 if not exists mytable(sid int,sname string)
row format delimited fields terminated by '\005' stored as textfile
創建外部表
create external table if not exists pageview(pageid int,page_url string
comment 'The page URL')
row format delimited fields terminated by ','
location 'hdfs://mini1:9000/user/hive/warehouse/'
創建分區表
create table student_p(Sno int,Sname string,Sex string,Sage int,Sdept string)
partition by(part string) row format delimited fields terminated by ',' stored as textfile;
創建帶桶表
create table student(id int,age int,name string)
partitioned by(stat_date string)
clustered by(id) sorted by (age) into 2 buckets
row format delimited fields terminated by ',';
8、修改表
增加/刪除分區
語法結構
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');
alter table student add partition(stat_date='20140101') location '/user/hive/warehouse/student' partition(stat_date='20140102')
9、重命名表
alter table table_name rename to new_table_name;
10、增加/更新列
語法結構
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]
11、顯示命令
show tables
show databases
show partitions
show functions
desc extended t_name;
desc formatted table_name;
3.2、DML操作
1、Load
語法結構
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 查找文件
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 中的文件名沖突,那么現有的文件會被
新文件所替代。
5、具體實例
1\加載相對路徑數據
load data local inpath 'buckets.txt' into table student partition(stat_date='20131231')
2\加載絕對路徑數據
load data local inpath '/root/app/datafile/buckets.txt' into table student partition(stat_date='20131231');
3\加載包含模式數據
load data local inpath 'hdfs://mini1:9000/user/hive/warehouse/student/stat_date=20131230/buckets.txt'
4\overwrite
load data local inpath 'buckets.txt' overwrite into table student parttition(stat_date='20131229');
2、Insert
語法結構
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
具體實例:
基本模式插入
insert overwrite table student partition(stat_date='20140101')
select id,age,name from student where stat_date='20131229'
多插入模式插入
from student
insert overwrite table student partition(stat_date='20140102')
select id,age,name where stat_date ='20131229'
insert overwrite table student partition(stat_date='20140103')
select id,age,name where stat_date ='20131229'
自動分區模式
insert overwrite table student partition(stat_date)
select id,age,name,stat_date from student where stat_date='20140101'
3導出表數據
語法結構
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、導出數據到本地
insert overwrite local directory '/root/app/datafile/student'
select * from student
數據寫入到文件系統時進行文本序列化,且每列用^A來區分,\n為換行符。
用more命令查看時不容易看出分割符,可以使用: sed -e 's/\x01/|/g' filename 來查看。
2、導出數據到hdfs
insert overwrite directory 'hdfs://mini1:9000/user/hive/warehouse/mystudent'
select * from student;
4、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 不是全局排序,其在數據進入reduce前完成排序,因此如果用sort by進行排序
並且設置mapred.reduce.task>1,則sort by 只保證每個reducer的輸出有序,不保證全局有序
3、distribute by 根據distribute by 指定的內容將數據分到同一個reducer
4、Cluster by除了具有distribute by 的功能外,還會對該字段進行排序,因此,常常認為cluster
by=distribute by + sort by
5、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 個表的連接。
LEFT SEMI JOIN是IN/EXISTS的高效實現。
6、Hive Shell參數
Hive自定義函數和Transform
自定義函數類別
UDF 作用於單個數據行,產生一個數據行作為輸出。(數學函數,字符串函數)
UDAF(用戶定義聚集函數):接收多個輸入數據行,並產生一個輸出數據行。(count,max)
UDF開發實例
1、先開發一個java類,繼承UDF,並重載evaluate方法
2、打成jar包上傳到服務器
3、將jar包添加到hive的classpath
hive>add JAR /home/hadoop/udf.jar;
4、創建臨時函數與開發好的java class關聯
Hive>create temporary function toprovince as 'cn.itcast.bigdata.udf.ToProvince';
5、即可在hql中使用自定義的函數strip
Select strip(name),age from t_test;
Transform實現
Hive的 TRANSFORM 關鍵字提供了在SQL中調用自寫腳本的功能
適合實現Hive中沒有的功能又不想寫UDF的情況