第一節(jié):
hive作為大數(shù)據(jù)中重要組成的一部分湖苞,它是基于Hadoop的映射數(shù)據(jù)庫表,其提供的Hue可以將簡單的HQL語句轉(zhuǎn)化為MapReduce任務(wù)執(zhí)行吗浩,大大簡化了學(xué)習(xí)成本揩页;HQL大體上和SQL相同,只是有少部分sql語句在hql上兼容不好速缆,具體出現(xiàn)的錯(cuò)誤日后再行補(bǔ)上降允。
基礎(chǔ):
創(chuàng)建數(shù)據(jù)庫:Create database ?test;
創(chuàng)建數(shù)據(jù)表:Create table if not exists test(id int comment ‘序列號(hào)', name string comment ‘姓名', ?age string comment?‘年齡', sex string comment '性別'….)?ROW?FORMAT?DELIMITED?FIELDS?TERMINATED?BY?‘,’ ?# ?設(shè)置列分割符為’,’,為后面導(dǎo)入hdfs的csv文件作準(zhǔn)備; ?
? ? 3.修改數(shù)據(jù)表結(jié)構(gòu): alter table test addcolumns(address ?string); # 增加表列
修改表名稱:alter table test rename to tt ;
修改列:ALTER TABLE test change name new_name string;?
刪除列 : alter table test drop name;
刪除表:drop table test ;
去除導(dǎo)入數(shù)據(jù)的第一行或最后一行:create table test(id int, name string) TBLPROPERTIES('skip.header.line.count’=‘*’/?‘skip.footer.line.count'=‘*') # 去除首/尾 *行;
上傳文件到HDFS:
?? ?1. 將本地?cái)?shù)據(jù)push到hdfs艺糜, hdfs?dfs -put localfile_path remote_filepath;
2. 在hue上執(zhí)行LOAD?DATA?INPATH?‘remote_filepath’[overwrite]INTO?TABLE?text; # 將hdfs的文件導(dǎo)入到hive中剧董;
?注:如果導(dǎo)入數(shù)據(jù)出現(xiàn)Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive, 可能是hdfs文件權(quán)限問題破停; 解決方案:hdfs dfs -chomd 777 ?filename (文件在hdfs的路徑);load data local?inpath指的直接從本地文件中加載翅楼,先將本地文件拷貝到hdfs,然后再使用真慢;overwrite 是將原先表的數(shù)據(jù)進(jìn)行覆蓋? ?3. select count(*) from test; ?# 查詢記錄毅臊,驗(yàn)證數(shù)據(jù)是否導(dǎo)入成功;
? ? 4.Select * from test limit 10;
5.SELECT?DISTINCT('columns_name')?from?test;
在有了全量表之后黑界,需要將全量表根據(jù)業(yè)務(wù)拆分為多張子表的需求時(shí)管嬉,可以根據(jù)字表的字段從全表中的數(shù)據(jù)選擇性導(dǎo)入相應(yīng)的數(shù)據(jù),例如:
create table if not exists test1(id int comment?‘ID號(hào)’, name string comment '姓名’);
Insert overwrite table test1 select id, name from test; <一條一條數(shù)據(jù)插入效率很慢>
Create table if not exists test2 as select name from test; <復(fù)制非分區(qū)表>
如果是分區(qū)表朗鸠,先要復(fù)制表結(jié)構(gòu): create table test3 like test; 之后將分區(qū)數(shù)據(jù)拷貝到對(duì)應(yīng)的目錄下:dfs -cp -f /user/hive/warehouse/test/*?/user/hive/warehouse/test3/; 最后同步信息 msck repair ?table test3;
上面所講的所謂的內(nèi)部表蚯撩,還有一種叫做外部表,例如:
create?external table if not exists ex_test(id int, name string, sex string) partitioned by(birth string) row format?delimited fields terminated by?‘\t’ location?‘file_path’<文件在hdfs路徑>
注:如果沒有指定location,則會(huì)在/usr/hive/warehouse/建立一個(gè)表目錄烛占,之后將hdfs的數(shù)據(jù)移動(dòng)到該目錄下求厕;
外部表和內(nèi)部表的區(qū)別:內(nèi)部表是將hdfs移動(dòng),當(dāng)內(nèi)部表刪除之后扰楼,對(duì)應(yīng)的數(shù)據(jù)也會(huì)被刪除呀癣,而外部表則是刪除之后,其數(shù)據(jù)還在指定的目錄中弦赖;
Hive數(shù)據(jù)存儲(chǔ)方式:1.Txtfile<默認(rèn)项栏,不壓縮>; 2.sequencefile<二進(jìn)制文件支持,壓縮類型None蹬竖,Record沼沈,Block>; 3.RcFile(直接對(duì)數(shù)據(jù)進(jìn)行分開流酬,保證同一個(gè)record在一個(gè)塊上,加載開銷大列另,但是壓縮比大芽腾,查詢響應(yīng)快,推薦使用)页衙;4.Orcfile<后出來的>
第二節(jié):
hive的分區(qū)操作摊滔,因?yàn)閔ive在大規(guī)模的數(shù)據(jù)中進(jìn)行查詢相關(guān)操作,適當(dāng)?shù)姆謪^(qū)有助于提升查詢數(shù)據(jù)的效率店乐;
例如創(chuàng)建一個(gè)test表:
Create table if not exists test(id int, name string) partitioned by( sex string) row format delimited fields terminated by ‘,’ ;
根據(jù)性別sex進(jìn)行分區(qū)艰躺,分區(qū)類似于將數(shù)據(jù)放在不同的文件夾下,因而在hive進(jìn)行數(shù)據(jù)查找時(shí)可以根據(jù)where條件分區(qū)查找而不用進(jìn)行全表掃描眨八,從而提高效率腺兴;但也不是分區(qū)越多越好;由于分區(qū)對(duì)應(yīng)的是hdfs上一個(gè)個(gè)小文件廉侧,當(dāng)小文件過多页响,會(huì)導(dǎo)致mapper任務(wù)越多,從而導(dǎo)致初始化任務(wù)消耗資源過多段誊,影響性能拘泞;而且hive的創(chuàng)建文件數(shù)有限制,太多分區(qū)可能超出限制導(dǎo)致出錯(cuò)枕扫;總之要根據(jù)實(shí)際的需求創(chuàng)建分區(qū)陪腌;
添加一個(gè)或多個(gè)分區(qū):alter table test add partition(brith=’1992’), partition(birth=‘1995’),..;
刪除分區(qū):alter table test drop partition(birth=’1992’);
查看分區(qū):show partitions test;
重命名分區(qū): alter table test partition(birth=’1992’) rename to partition(birth=‘1995’);
同步hdfs的分區(qū)信息:msck repairtable test;
分桶表 == MapReduce分區(qū):
將表按照字段列進(jìn)行劃分并排序;
Create table if not exists test(id int, name string, sex string) clustered by(id) sorted by (name string) into 4 buckets row format delimited fields terminated by ‘\t’ stored as textfile;
插入數(shù)據(jù):
insert table 桶表名 select * from table **;
常用的內(nèi)置方法:
Case when ‘’ then ‘’ else '' end ;
Select id, case when num>100 then ‘0-99’ when num<1000 then ‘100-1000’ else ‘>1000’ end from table_name ;
等同于: select id from table_name ?where num<100 ; &&?select id from table_name ?where num>100 and num<1000; &&?select id from table_name ?where num>1000;
If (單個(gè)條件判斷):
SELECT title, if(num>100,0,1) as n,num from car_back LIMIT 10;