大數(shù)據(jù)hadoop生態(tài)體系之Hive的基本操作(15)

Hive數(shù)據(jù)倉(cāng)庫(kù)基于shell命令行基本操作(DDL/DML):

首先啟動(dòng)hive數(shù)據(jù)庫(kù)倉(cāng)庫(kù)的shell腳本模式:

命令:/opt/mysoft/hive/bin/hive

1> 查看當(dāng)前Hive中有哪些數(shù)據(jù)庫(kù)

? ? ?hive初始化后,會(huì)生成一個(gè)默認(rèn)的default數(shù)據(jù)庫(kù);往往根據(jù)項(xiàng)目不同,會(huì)建立不同業(yè)務(wù)的hive數(shù)據(jù)庫(kù);

? ? ?命令:show databases;

2>?創(chuàng)建數(shù)據(jù)庫(kù)

? ? ?命令:create database test;?? ??

3>?打開(kāi)/使用數(shù)據(jù)庫(kù)

? ? ?命令:use test;

4> 查看數(shù)據(jù)庫(kù)中的所有表

? ? ?命令:show tables;

5>?基于打開(kāi)的數(shù)據(jù)庫(kù)建表

? ? ?命令:create table stu (id int,name string) ?row format delimited fields terminated by ',';

? ? ?查看創(chuàng)建成功后的表結(jié)構(gòu):

? ? ?命令:desc stu;

6>?加載數(shù)據(jù)到表中

? ? ?本地文件方式:

? ? ?命令:load data local inpath '/opt/mysoft/stu.txt' into table stu;??

? ? ?HDFS遠(yuǎn)程服務(wù)器方式:

? ? ?命令:load data inpath 'hdfs://hadoop:9000/output/*' into table stu;

語(yǔ)法命令:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

?? [(col_name data_type[COMMENT col_comment], ...)]

?? [COMMENT table_comment]

?? [PARTITIONED BY (col_namedata_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 創(chuàng)建一個(gè)指定名字的表。如果相同名字的表已經(jīng)存在,則拋出異常;用戶可以用 IF NOT EXISTS 選項(xiàng)來(lái)忽略這個(gè)異常。

2、 EXTERNAL關(guān)鍵字可以讓用戶創(chuàng)建一個(gè)外部表,在建表的同時(shí)指定一個(gè)指向?qū)嶋H數(shù)據(jù)的路徑(LOCATION)。

Hive 創(chuàng)建內(nèi)部表時(shí),會(huì)將數(shù)據(jù)移動(dòng)到數(shù)據(jù)倉(cāng)庫(kù)指向的路徑;若創(chuàng)建外部表,僅記錄數(shù)據(jù)所在的路徑,不對(duì)數(shù)據(jù)的位置做任何改變。在刪除表的時(shí)候,內(nèi)部表的元數(shù)據(jù)和數(shù)據(jù)會(huì)被一起刪除,而外部表只刪除元數(shù)據(jù),不刪除數(shù)據(jù)。

3、 LIKE 允許用戶復(fù)制現(xiàn)有的表結(jié)構(gòu),但是不復(fù)制數(shù)據(jù)。

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;

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,...)]

hive建表的時(shí)候默認(rèn)的分割符是'\001',若在建表的時(shí)候沒(méi)有指明分隔符,load文件的時(shí)候文件的分隔符需要是'\001';若文件分隔符不是'001',程序不會(huì)報(bào)錯(cuò),但表查詢的結(jié)果會(huì)全部為'null';

用vi編輯器Ctrl+v然后Ctrl+a即可輸入'\001' ----------->? ^A

SerDe是Serialize/Deserilize的簡(jiǎn)稱,目的是用于序列化和反序列化。

Hive讀取文件機(jī)制:首先調(diào)用InputFormat(默認(rèn)TextInputFormat),返回一條一條記錄(默認(rèn)是一行對(duì)應(yīng)一條記錄)。然后調(diào)用SerDe(默認(rèn)LazySimpleSerDe)的Deserializer,將一條記錄切分為各個(gè)字段(默認(rèn)'\001')。

Hive寫文件機(jī)制:將Row寫入文件時(shí),主要調(diào)用OutputFormat、SerDe的Seriliazer,順序與讀取相反。

可通過(guò)desc formatted 表名;進(jìn)行相關(guān)信息查看。

當(dāng)我們的數(shù)據(jù)格式比較特殊的時(shí)候,可以自定義SerDe。

5、 PARTITIONED BY

在hive Select查詢中一般會(huì)掃描整個(gè)表內(nèi)容,會(huì)消耗很多時(shí)間做沒(méi)必要的工作。有時(shí)候只需要掃描表中關(guān)心的一部分?jǐn)?shù)據(jù),因此建表時(shí)引入了partition分區(qū)概念。

分區(qū)表指的是在創(chuàng)建表時(shí)指定的partition的分區(qū)空間。一個(gè)表可以擁有一個(gè)或者多個(gè)分區(qū),每個(gè)分區(qū)以文件夾的形式單獨(dú)存在表文件夾的目錄下。表和列名不區(qū)分大小寫。分區(qū)是以字段的形式在表結(jié)構(gòu)中存在,通過(guò)describe table命令可以查看到字段存在,但是該字段不存放實(shí)際的數(shù)據(jù)內(nèi)容,僅僅是分區(qū)的表示。

6、 STORED AS SEQUENCEFILE|TEXTFILE|RCFILE

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

TEXTFILE是默認(rèn)的文件格式,使用DELIMITED子句來(lái)讀取分隔的文件。

6、CLUSTERED BY INTO num_buckets BUCKETS

對(duì)于每一個(gè)表(table)或者分,Hive可以進(jìn)一步組織成桶,也就是說(shuō)桶是更為細(xì)粒度的數(shù)據(jù)范圍劃分。Hive也是針對(duì)某一列進(jìn)行桶的組織。Hive采用對(duì)列值哈希,然后除以桶的個(gè)數(shù)求余的方式?jīng)Q定該條記錄存放在哪個(gè)桶當(dāng)中。

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

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

(2)使取樣(sampling)更高效。在處理大規(guī)模數(shù)據(jù)集時(shí),在開(kāi)發(fā)和修改查詢的階段,如果能在數(shù)據(jù)集的一小部分?jǐn)?shù)據(jù)上試運(yùn)行查詢,會(huì)帶來(lái)很多方便。

hive cli中顯示列名: 進(jìn)入hive cli后 set hive.cli.print.header=true;

案例:

1> 創(chuàng)建普通表,字段以逗號(hào)進(jìn)行分割,默認(rèn)分隔符是'\001', vi 編輯器的:ctrl + v 和 ctrl+a

create table tb_stu(id int, name string) row format delimited fields terminated by ',';?

2> 創(chuàng)建分區(qū)表,有時(shí)候數(shù)據(jù)量太大,我們只需要查詢一部分,可以使用字段分區(qū),分區(qū)字段不能和已有的字段重復(fù)

create table tb_stu2(id int,name string) partitioned by (age int) row format delimited fields terminated by ',';

加載數(shù)據(jù):load data local inpath '/opt/mysoft/hivedata/student.txt' INTO TABLE tb_stu2 PARTITION(age=20);

加載數(shù)據(jù)時(shí)如果添加local加載的是本地?cái)?shù)據(jù),如果沒(méi)有l(wèi)ocal加載的是hdfs服務(wù)器上的數(shù)據(jù)。

3> 創(chuàng)建雙分區(qū)表 使用partition(year string,hour int)

create table tb_stu3(id int,name string) partitioned by (dt string,hour string) row format delimited fields terminated by ',';

加載數(shù)據(jù):load data local inpath '/opt/mysoft/hivedata/student.txt' into table tb_stu3 partition(dt = '20200404',hour='23');

4> 分桶表 (cluster by into num bucked )

? ? 指定開(kāi)啟分桶:set hive.enforce.bucketing = true;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? set mapreduce.job.reduces = 4;

? ? 創(chuàng)建分桶表:

? ? create table tb_stu4(id int,name string) clustered by (id) sorted by(id desc) into 4 buckets row format delimited fields terminated by ',';

? ? 導(dǎo)入數(shù)據(jù)(需要前創(chuàng)建一個(gè)同樣字段的臨時(shí)表,然后導(dǎo)入數(shù)據(jù),再?gòu)呐R時(shí)表中查詢數(shù)據(jù)導(dǎo)入到分桶表):

? ? insert overwrite table tb_stu4 select * from tb_stu cluster by (id)

? ? 分桶表需要使用mr程序進(jìn)行計(jì)算之后再裝載導(dǎo)入到分桶表中,根據(jù)分桶字段的hash值計(jì)算分桶

5> 內(nèi)部表和外部表(EXTERNAL), 主要區(qū)別在于看有沒(méi)有加 external關(guān)鍵字,內(nèi)部表在hive的默認(rèn)路徑下,外部表可以指定目錄,特別是有比較大的數(shù)據(jù)的時(shí)候,不用上傳到hive,直接在hdfs上的文件目錄建立關(guān)聯(lián)。

創(chuàng)建表: create external table tb_stu5(id int,name string) row format delimited fields terminated by ',' location '/input';

外部表當(dāng)元數(shù)據(jù)表刪除的時(shí)候,外部表對(duì)象應(yīng)的數(shù)據(jù)文件不會(huì)被刪除,內(nèi)部表則元數(shù)據(jù)和表文件一塊被刪除。

6> like 語(yǔ)句: 復(fù)制一個(gè)表的表結(jié)構(gòu),但不會(huì)復(fù)制數(shù)據(jù)。

? ? create table stu_like like tb_stu;

7> 修改分區(qū)表:

alter table tb_stu2 partition(age = 20) rename to partition(age=50);

8> hive表的join查詢:

select * from tb_stu t1 join tb_stu2 t2 on t1.id = t2.id where t1.id = 5;

9> 導(dǎo)出數(shù)據(jù):

? ? 導(dǎo)出到本地目錄:

????insert overwrite local directory '/opt/data' select * from tb_stu;

? ? 導(dǎo)出到hdfs目錄:

? ? insert overwrite directory '/input' select * from tb_stu;

10> hive 中創(chuàng)建dual表

? ? ?create table dual(id string);

? ? 在opt/mysoft/hivedata目錄中創(chuàng)建 dual.txt 文件,文件中只保存一個(gè)空格。

? ? 加載數(shù)據(jù)到dual表: load data local inpath '/opt/mysoft/hivedata/dual.txt' into table dual;

? ? 測(cè)試:select substr('hello world',2,3) from dual;

11> 自定義UDF開(kāi)發(fā)函數(shù):

? ? ? hive 可以使用自定義UDF函數(shù)。

? ? 定義步驟:使用maven創(chuàng)建一個(gè)java工程

? ? 1. 導(dǎo)入需要的依賴jar包

? ??????hive-exec-1.2.1.jar和hadoop-common-2.7.4.jar依賴

? ? 2.創(chuàng)建一個(gè)類,繼承org.apache.hadoop.hive.ql.exec.UDF類,重載evaluate()方法,實(shí)現(xiàn)自己的定義方法的業(yè)務(wù)邏輯

? ? 3.打成jar包上傳到服務(wù)器

? ? 4.將jar包添加到hive的classpath

????????hive>addJAR /home/hadoop/udf.jar;

? ? 5. 創(chuàng)建臨時(shí)函數(shù)與開(kāi)發(fā)好的java class關(guān)聯(lián)

? ??????create temporary function tolowercase as 'com.hive.test.udffunc';

? ? ?6.使用自定義函數(shù):select tolowercase('ABCDEF'); 輸出結(jié)果:abcdef

? ??????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容