1. 程式人生 > >hive的語法命令介紹

hive的語法命令介紹

1.hive的基本語法:

create databases mydb #建立資料庫
show databases            #檢視所有的庫
use mydb                      #切換資料庫
create table t_user(id int ,name string,age int)  #建立表
create table t_user(id int ,name string,age int) row format delimited fields terminated by '分隔符'  #指定分隔符的建表語句
insert into table t_user values(值1,值1,值1)     #插入資料
select * from t_table       #查詢語句
load data inpath 'HDFS path' into table t_name  #在hdfs中匯入資料
load data local inpath 'linux path' into table t_name #匯入Linux資料到hive

2.hive的DDL操作:

(1)對hive庫的操作:

建庫

create database if not exists myhive   #如果不存在則建立該資料庫
create database if not exists myhive2 localtion 'hdfs path'  #指定該庫的位置

檢視庫

show databases;                            #檢視hive中所有的資料庫
desc databases dbname ;              #顯示資料庫的詳細資訊
select current_database();             #檢視正在使用的資料庫
show create database db_name ;  #檢視建庫語句

刪除庫

drop databases db_name restrict;
drop database if exists dbname;
#注意:預設情況下,hive不允許刪除包含表的庫,有兩種辦法:
1. 手動刪除所有的表,然後在刪除庫
2. 使用cascade 關鍵字:drop database myhive cascade ;

(2)對hive表的操作:

建表
語法分析:

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]
[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]   #指定分隔符
fields terminated by ‘’  #指定列分割符
lines terminated by ‘’  #指定行分隔符
[STORED AS file_format]   #指定資料儲存格式
[LOCATION hdfs_path]      #指定資料儲存目錄 (在建立外部表時使用)

建表舉例:

#內部表
create table if not exists student(id int ,name string) row format delimited fields terminated by ','      

#外部表
create external table if not exists student (id int ,name string) row format delimited fields terminated by ',' location '/hive/data/';
#分割槽表
create table  if not exists student (id int ,name string) partitioned by (age int conmment 'partitioned comment') row format delimited fields terminated by ',' ;   #分割槽欄位的欄位名稱,不能是表中的任意一個欄位
#建立分桶表
create table if not exists  student (id int ,name string,age int ) clustered by (age) sort by (age desc) into 10 buckets row format delimited fields terminated by ',' ;   #分桶欄位一定要是表中的屬性欄位 
#like 方式
create table student like t_student ;   #複製一個表結構,分割槽表和分桶表也同樣可以複製(分割槽表只能複製在建立表的時候的資訊,之後新增的資訊不能複製)
#CTAS
create table student as select * from t_student #建立表並複製

修改表屬性

alter table old_name rename to new_name ;   #修改表名
alter table t_name set tb_properties (property_name=roperty_val)  #修改表的屬性
alter table t_name set serdeproperties('field.delim'='-');   #修改列的分隔符
alter table t_name add cloumns(f_name type) #增加一個欄位
alter table t_name drop   #hive本身不支援
alter table t_name replace columns(id int ,name string )  #替換所有的列
alter table t_name change old_field_name new_field_name type [first|after field] #修改欄位的名稱、型別以及位置
#接下來是對分割槽表操作:
alter table t_name add partition(分割槽欄位=‘value’)  #新增一個分割槽
alter table t_name add partition(分割槽欄位=‘value’) partition (分割槽欄位=‘value’)  #新增多個分割槽
alter table t_name drop partition(分割槽欄位='value')  #刪除分割槽
alter table t_name partition(分割槽欄位=‘value’) set location 'hdfs path' #修改分割槽路徑
alter table t_name partition(分割槽欄位=‘value’) enable no_drop ; #防止分割槽被刪除
alter table t_name partition(分割槽欄位=‘value’) enable offline #防止分割槽被查詢

刪除表

drop tab;e if exists t_name ;   #刪除表
注意:
1. 內部表刪除:元資料和資料都刪
2. 內部表刪除:元資料和資料都刪
3. 分割槽表(內部表):所有的分割槽都會被刪除,元資料和資料都刪
4. 分桶表的刪除和普通表的刪除沒有任何區別
truncate table t_name ;  #清空表的內容

對錶的常見操作

show tables ;  #檢視庫下的所有表
show partitions t_name;  # 查看錶的分割槽
show partitions 表名 partition(分割槽欄位=‘value’)  #檢視某個分割槽
desc t_name ;   #查看錶的詳細資訊
desc extended 表名  #查看錶的詳細資訊   
desc formatted 表名  #查看錶的詳細資訊

3.hive的DML操作:

(1)資料的裝載:

load data local inpath 'linux path' into table t_name ;   #本地匯入
local data inpath 'hdfs path' into table t_name    #從hdfs中匯入
#注意:如果是內部表的話,在hdfs匯入,那麼原本的資料會被移動到相應的表的目錄下
load data local inpath 'linux path ' overwrite into table 表名;  #覆蓋匯入

(2)資料的插入:

注意

insert into //表示追加操作
insert overwrite   //表示覆蓋插入操作
insert into table t_name(fields1,fields2,fields3) values(value1,value2,value3)  #插入一條資料
insert into table t_name select * from tt_name;  #利用查詢,將結果匯入表中
#分割槽表的多重插入
insert into talbe student_ptn partition(department=’SC’) select id ,name,age ,sex from student where dept=’ SC’; 
insert into talbe student_ptn partition(department=’AC’) select id ,name,age ,sex from student where dept=’ AC’;
insert into talbe student_ptn partition(department=’ES’) select id ,name,age ,sex from student where dept=’ ES’;
上面的方法是使用單個sql去查詢表,但是這裡每執行一個sql就需要對student表中的所有資料進行掃描,效率太低!
轉換:
from student 
insert into table student_ptn partition(department=’SC’) select id ,name,age ,sex where dept=’ SC’; 
insert into talbe student_ptn partition(department=’AC’) select id ,name,age ,sex  where dept=’ AC’;
insert into talbe student_ptn partition(department=’ES’) select id ,name,age ,sex where dept=’ ES’;
這種方式進行資料的處理,只需要掃描表一次,整個MR程式就是一個輸入多個輸出,如果指定的分割槽不存在,在執行這條語句時會自動建立。
# 分桶表的資料插入,這裡分桶表只能使用insert進行資料插入
insert into table stu_bck select * from 表名  #和普通的插入一樣
**分桶的原則:分桶欄位的hashcode值%分桶個數=  相同的值分在一組

動態分割槽插入和靜態分割槽插入
靜態分割槽插入:要進行資料插入的資料的定義是手動指定的(分割槽在插入之前指定)
動態分割槽插入:用來解決靜態分割槽插入的缺點。按照某個分割槽欄位的值進行判斷,每遇到一個不同的值,當前的程式自行進行判斷來建立對應的分割槽
舉例:

#靜態分割槽插入:
load data local inpath “路徑” into table 表名 partition(dpt=’’)
insert into talbe student_ptn partition(department=’SC’) select id ,name,age ,sex where dept=’ SC’;
#動態分割槽插入:
insert into table t_name partition(欄位名) select * from tt_name #這裡查詢的表的最後一個欄位需要是分割槽欄位。
#多分割槽動態插入:
insert into table stu_ptn01 partition(sex,department) select id,name,age,sex,department from student_manager;  #只要查詢欄位的最後幾個欄位是分割槽欄位即可,順序不能顛倒

注意:如果想使用動態分割槽插入需要在hive中開啟幾個引數:

set hive.exec.dynamic.partiton=true;  #開啟動態分割槽開關
set hive.exec.dynamic.partition.mode=nonstrict ;  #關閉動態分割槽插入的不合法約束。

靜態分割槽插入和動態分割槽插入的區別
 - 靜態分割槽插入資料後,需要指定分割槽的名字,而動態分割槽不需要
 - 靜態分割槽中可能會存在某一個分割槽沒有資料,分割槽的目錄是一個空目錄,動態分割槽的時候根據實際的資料生成分割槽,每一個分割槽至少有一條資料
 - 3) 動態分割槽的時候,每一個分割槽都會對應配置檔案中設定的reducetask的個數,
set reducetask=3

(3)資料的匯出:

#單重匯出
insert overwrite local directory 'linux path' select * from t_name;
#多重匯出
from t_name insert overwrite local directory 'linux path' select * where ...
insert overwrite local directory 'linux path' select * where...

4.hive的DQL操作:

查詢語句的書寫順序:select fields ... from [join] where group by having order by limit
查詢語句的執行順序:from ----join ----group by ---having ---select ---ordey by -----limit

(1)hive中的join

特點
  - Hive中連線,只支援等值連線不支援不等值連線
  - Hive中and連線,不支援or
  - Hive支援多表關聯,但是hive中進行關聯的時候儘量避免笛卡爾積
  - Hive支援in 和 exists 但是效率特別低
舉例:

#內連線
select a.id aid,a.name name,b.id bid,b.score score from test_a a inner join test_b b on a.id=b.id;  (交集)
#左外連結:以join左側的表為基礎表  左側的表的所有資料都會顯示  右側可以關聯上的就會補全  關聯不上 null補充
select a.id aid,a.name name,b.id bid,b.score score from test_a a left join test_b b on a.id=b.id;
#右外連結:以join右側的表為基礎
select a.id aid,a.name name,b.id bid,b.score score from test_a a right join test_b b on a.id=b.id;
#全外連結:取兩個表的並集
select a.id aid,a.name name,b.id bid,b.score score from test_a a full join test_b b on a.id=b.id;
#半連線,相當於內連線  取左半表的資料,左表中在右表中出現關聯上的資料
select * from test_a a left semi join test_b b on a.id=b.id;

關於 left semi join 的特點
left semi join 是對hive中的exists/in的一個更高階額的操作。
  - left semi join 的限制是, JOIN 子句中右邊的表只能在 ON 子句中設定過濾條件,在 WHERE 子句、SELECT 子句或其他地方過濾都不行。
  - left semi join 是隻傳遞表的 join key 給 map 階段,因此left semi join 中最後 select 的結果只許出現左表。
  - 因為 left semi join 是 in(keySet) 的關係,遇到右表重複記錄,左表會跳過,而 join 則會一直遍歷。這就導致右表有重複值得情況下 left semi join 只產生一條,join 會產生多條,也會導致 left semi join 的效能更高。
hive的語法命令介紹

(2)hive中的排序

order by
特點:局排序
例:select * from 表名 order by 欄位 desc; (降序排序)

sort by
特點:sort by 是一個區域性排序,在每一個reduce中進行排序,當reduceTask個數為1個時,這時與全域性排序相同
原理:sort by 在進行分每一個reduceTask中的資料時,時隨機選擇的欄位進行分配
例:select * from 表名sort by 欄位;

distribute by
特點:按照指定欄位分桶,在每個桶中進行排序。
例1:select * from 表名 distribute by 欄位 (欄位.hash%分桶個數)
例2:select * from 表名 distribute by 分桶欄位 sort by 排序 欄位 #按照指定欄位分桶,在每一個桶中進行排序

cluster by
特點:既分桶又排序
例:select * from 表名 cluster by 分桶排序欄位
注意:當分桶欄位和排序欄位相同時:distribute by+ sort by= cluster by,否則distribute by+ sort by功能更強大一些!

(3)union和union all區別

union和union all:都是將查詢結果進行拼接,(連線的兩個表的結構必須相同)

select * from xxx  union selecet * from xxx
select * from xxx  union all selecet * from xxx

union:表示去重連線
union all :表示不去重連線