Hive0.14 語法

創建數據庫

create database mydb;

切換數據庫

use mydb;

創建數據庫

create database if not exists mydb;

創建內部表表的同時加載數據

create table student_test(id INT, info struct<name:STRING, age:INT>)   ROW FORMAT DELIMITED FIELDS

TERMINATED BY ','  COLLECTION ITEMS TERMINATED BY ':';

創建外部表

create external table xxx location '/dir';

查看錶信息

describe t1;

查看表的詳細信息

describe extended t1;

刪除數據庫級聯刪除數據庫中的表

DROP DATABASE [IF EXISTED] mydb [CASCADE];

修改列的名稱、類型、位置、註釋

ALTER TABLE t3 CHANGE COLUMN old_name new_name String COMMENT '...' AFTER column2;

增加列

ALTER TABLE t3 ADD COLUMNS (gender int);

從本地文件系統加載數據到表中

load data local inpath '/root/inner_table.dat' into table t1;

從hdfs加載數據到表中

load data inpath '/root/inner_table.dat' into table t1;

創建分區表

create table partition_table(rectime string,msisdn string) partitioned by(province string,city string) row format

delimited fields terminated by '\t' stored as TEXTFILE;

加載數據到分區表

load data local inpath 'files/stu' into table partition_table partition(province='beijing',city='chaoyang');

查看分區

show partitions partition_table;

刪除分區

alter table partition_table drop partition (daytime='2013-02-04',city='bj')元數據,數據文件刪除,但目錄

daytime=2013-02-04還在


桶是更爲細粒度的數據範圍劃分,它能使一些特定的查詢效率更高,比如對於具有相同的桶劃分並且join的列剛好就

是在桶裏的連接查詢,還有就是示例數據,對於一個龐大的數據集我們經常需要拿出來一小部分作爲樣例,然後在樣

例上驗證我們的查詢,優化我們的程序。

桶表是對數據進行哈希取值,然後放到不同文件中存儲。

創建表

create table bucket_table(id string) clustered by(id) sorted by (id) into 4 buckets;插入時先對id取hash值,然後對4取

模分到四個桶中

加載數據

set hive.enforce.bucketing = true;默認是false,啓用桶表必須先設置該變量

insert into table bucket_table select id from stu;   

insert overwrite table bucket_table select id from stu;覆蓋原來數據

數據加載到桶表時,會對分桶的字段取hash值,然後與桶的數量取模。把數據放到對應的文件中。


抽樣查詢

select * from bucket_table tablesample(bucket 1 out of 4 on id);

tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUT OF y)

y必須是table總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如,table總共分了64份,當y=32

時,抽取 (64/32=)2個bucket的數據,當y=128時,抽取(64/128=)1/2個bucket的數據。x表示從哪個bucket開始抽取。

例 如,table總bucket數爲32,tablesample(bucket 3 out of 16),表示總共抽取(32/16=)2個bucket的數據,分別爲

第3個bucket和第(3+16=)19個bucket的數據。


從文件中裝載數據

hive>LOAD DATA [LOCAL] INPATH '...' [OVERWRITE] INTO TABLE t2 [PARTITION (province='beijing')];

通過查詢表裝載數據

hive>INSERT OVERWRITE TABLE t2 PARTITION (province='beijing') SELECT * FROM xxx WHERE xxx

一次插入多個表

hive>FROM t4

 INSERT OVERWRITE TABLE t1 SELECT ...WHERE...

 INSERT OVERWRITE TABLE t2 PARTITION (...) SELECT ...WHERE...

 INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...


動態分區裝載數據【動態分區列寫在select子句最後
hive>set hive.exec.dynamic.partition=true; 啓用動態分區
hive>set hive.exec.dynamic.partition.mode=nostrict; 非嚴格模式
hive>set hive.exec.max.dynamic.partitions.pernode=1000;      最大分區數(目的是限制產生過多文件夾)

hive>INSERT OVERWRITE TABLE t3 PARTITION(province, city)
SELECT t.province, t.city FROM temp t;

如果是嚴格模式,必須指定一個靜態分區,不能全都是動態分區
hive>INSERT OVERWRITE TABLE t3 PARTITION(province='bj', city)
SELECT t.province, t.city FROM temp t WHERE t.province='bj';


導出hive中的數據

可以使用hadoop命令進行文件複製 hdfs dfs -cp source destination


完整建表語句(注意關鍵字順序)

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]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]
    [SKEWED BY (col_name, col_name, ...) ON ([(col_value, col_value, ...), ...|col_value, col_value, ...])
    [STORED AS DIRECTORIES]   ]
  [ [ROW FORMAT row_format]
    [STORED AS file_format] | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]   ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]     
  [AS select_statement]  (Note: not supported when creating external tables.)


hive處理的文件格式

TextFile: 普通文本文件,默認按該類型存儲 不做壓縮,磁盤開銷大,數據解析開銷大

SequenceFile:  Hadoop API提供的一種二進制文件支持 可分割、可壓縮 支持三種壓縮選擇:NONE, RECORD,

BLOCK。 Record壓縮率低,一般建議使用BLOCK壓縮

RCFile:是一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個record在一個塊上,避免讀一個

記錄需要讀取多個block。其次,block中數據按列式存儲,有利於數據壓縮和快速的列存取。

ORC:


textfile 存儲空間消耗比較大,並且壓縮的text 無法分割和合並 查詢的效率最低,可以直接存儲,加載數據的速度最高

sequencefile 存儲空間消耗最大,壓縮的文件可以分割和合並 查詢效率高,需要通過text文件轉化來加載

rcfile 存儲空間最小,查詢的效率最高 ,需要通過text文件轉化來加載,加載的速度最低


創建表按SequenceFile格式存儲,並設置壓縮形式,最後從其他表插入數據

create table test2(str STRING) STORED AS SEQUENCEFILE;

hive> set hive.exec.compress.output=true;

hive> set mapred.output.compress=true;

hive> set mapred.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;

hive> set io.seqfile.compression.type=BLOCK;

hive> set io.compression.codecs=com.hadoop.compression.lzo.LzoCodec;

hive> INSERT OVERWRITE TABLE test2 SELECT * FROM test1;


創建ORC格式存儲表

hive> create table t1_orc(id int, name string) row format delimited fields terminated by '\t' stored as orc

tblproperties("orc.compress"="ZLIB");

將其他類型的錶轉成ORC格式表

ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC

設置默認存儲格式爲ORC

hive> SET hive.default.fileformat=Orc;

hive> insert overwrite table t1_orc select * from t1;


What is a SerDe?

SerDe 是 "Serializer and Deserializer."的縮寫

Hive 使用 SerDe和FileFormat進行行內容的讀寫.

HDFS文件 --> InputFileFormat --> <key, value> --> Deserializer --> 行對象

行對象 --> Serializer --> <key, value> --> OutputFileFormat --> HDFS文件


Hive 使用如下FileFormat 類讀寫 HDFS files:

TextInputFormat/HiveIgnoreKeyTextOutputFormat: 讀寫普通HDFS文本文件.

SequenceFileInputFormat/SequenceFileOutputFormat: 讀寫SequenceFile格式的HDFS文件.


例:

CSV格式的文件也稱爲逗號分隔值(Comma-Separated Values,CSV,有時也稱爲字符分隔值,因爲分隔字符也可

以不是逗號。在本文中的CSV格式的數據就不是簡單的逗號分割的),其文件以純文本形式存儲表格數據(數字和文

本)。CSV文件由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字

符或字符串,最常見的是逗號或製表符。通常,所有記錄都有完全相同的字段序列。

默認的分隔符是

DEFAULT_ESCAPE_CHARACTER \

DEFAULT_QUOTE_CHARACTER  "     ---如果沒有,則不需要指定

DEFAULT_SEPARATOR        ,


CREATE TABLE csv_table(a string, b string) ROW FORMAT SERDE

'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES (   "separatorChar" = "\t",  

"quoteChar"     = "'",   "escapeChar"    = "\\")  STORED AS TEXTFILE;

紅色部分爲默認,也可以不寫。


該類org.apache.hadoop.hive.serde2.OpenCSVSerde即包含了InputFormat和OutputFormat來處理csv文件。



什麼時候可以避免執行MapReduce?

select * where語句中只有分區字段

set hive.exec.mode.local.auto=true;

group by語句

having語句

order by、sort by、distribute by、cluster by語句

order by是全局排序、sort by是單reduce排序、distribute by是分區字段;

cluster by是distribute by和sort by的簡寫


性能調優

set hive.map.aggr=true;

這個設置可以將頂層的聚合操作放在Map階段執行,從而減輕清洗階段數據傳輸和Reduce階段的執行時間,提升總

體性能。

缺點:該設置會消耗更多的內存。


表連接:

INNER JOIN

表中都有,且兩表符合連接條件

LEFT OUTER JOIN

左表中符合where條件出現,右表可以爲空

RIGHT OUTER JOIN

右表中符合where條件出現,左表可以爲空

FULL OUTER JOIN

LEFT SEMI-JOIN (左半連接)

左表中符合on條件出現,右表不出現

笛卡爾積

是m x n的結果

map-side JOIN


視圖的創建

CREATE VIEW v1 AS select * from t1;


lateral view用於和split, explode等UDTF一起使用,它能夠將一行數據拆成多行數據,在此基礎上可以對拆分後的數

據進行聚合。lateral view首先爲原始表的每行調用UDTF,UTDF會把一行拆分成一或者多行,lateral view再把結果組

合,產生一個支持別名表的虛擬表。

SELECT pageid, adid FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid;


自定義函數:

1、UDF函數可以直接應用於select語句,對查詢結構做格式化處理後,再輸出內容。

2、編寫UDF函數的時候需要注意一下幾點:

a)自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。

b)需要實現evaluate函數,evaluate函數支持重載。

4、步驟

a)把程序打包放到目標機器上去;

b)進入hive客戶端,添加jar包:hive>add jar /run/jar/udf_test.jar;

c)創建臨時函數:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';

d)查詢HQL語句:

SELECT add_example(8, 9) FROM scores;

SELECT add_example(scores.math, scores.art) FROM scores;

SELECT add_example(6, 7, 8, 6.8) FROM scores;

e)銷燬臨時函數:hive> DROP TEMPORARY FUNCTION add_example;

注:UDF只能實現一進一出的操作,如果需要實現多進一出,則需要實現UDAF


使用jdbc訪問hive

首先開啓hive遠程端口

Hive遠程服務啓動#hive --service hiveserver  -p 10002 >/dev/null  2>/dev/null &

JAVA客戶端相關代碼

Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver");

Connection con = DriverManager.getConnection("jdbc:hive://192.168.1.102:10000/wlan_dw", "", "");

Statement stmt = con.createStatement();

String querySQL="SELECT * FROM wlan_dw.dim_m order by flux desc limit 10";

ResultSet res = stmt.executeQuery(querySQL); 

while (res.next()) {

System.out.println(res.getString(1) +"\t" +res.getLong(2)+"\t" +res.getLong(3)+"\t" +res.getLong(4)+"\t"

+res.getLong(5));

}

JOIN 優化

1.hive對3個或3個以上的表進行join操作時,如果每個on字句都使用相同的連接鍵的話,只會產生一個MapReduce

job。

2.hive會假定查詢中最後一個表示最大的那個表。在對每行記錄進行連接操作時,會將其他表緩存起來,然後掃描最

後那個表進行計算。所以要保證從左到右表的大小是依次增加的。也可以在查詢語句中加入 /*+STREAMTABLE(表名

或別名)*/,指定哪張是最大的表。

3.避免笛卡爾積,select * from a join b where ....。在執行where過濾前首先會對a表和b表進行笛卡爾積,導致過程非

常緩慢,在hive中設置hive.mapred.mode=strict可以阻止笛卡爾積。

4.map-side join 如果連接查詢中只有一張表是小表,可以將小表中的數據放到內存中,在map端就可以進行連接操作

省略了reduce端的過程。需要設置 hive.auto.convert.join=true 並設置小表的大小hive.mapjoin.smalltable.filesize單位

是字節。或在查詢中加入 /*+ MAPJOIN(表名或別名)*/







發佈了84 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章