1. 程式人生 > >Hive基礎理論及表的型別

Hive基礎理論及表的型別

什麼是Hive?

Hive是建立在Hadoop上的,用來構建資料倉庫的工具,裡面有表的概念,可以使用SQL語句實現儲存、查詢和分析儲存在 HDFS上的資料,這些SQL語句在Hive中稱為HQL,語法和SQL語句基本一樣。 由於資料是雜亂無章的,所以Hive需要一份關於這些資料的元資料來管理和操作這些資料。這份元資料包括:

元資料(
行的分隔符(在對映成表的時候知道在哪裡分行顯示)
欄位分隔符(在對映成表的時候知道在哪裡分列顯示)
欄位的型別
欄位的名稱
)

在Hive中,我們把資料儲存在HDFS中,元資料預設儲存在Hive自帶的Derby資料庫中,由於Derby不能實現併發訪問,所以我們一般使用mysql進行替換。

Hive的原理

Hive 將使用者的HQL 語句進行解析,優化,最終把一個個的HQL語句轉換為MapReduce 作業提交到Hadoop 叢集上,Hadoop進行作業的排程及監控,作業完成後將執行結果返回給使用者。所以,Hive並不進行計算,只是把HQL解析為MapperReduce在HDFS叢集中執行而已,所以Hive的效率並不高。

Hive表的型別

hive中有5種表:

1. 內部表

資料預設儲存在/user/hive/warehouse,由hive自身管理,刪除內部表會同時刪除儲存資料和元資料。

建表方式一:
create table t1(
	    id	INT,
	    name STRING,
	    age INT
, gfs ARRAY<STRING>, address MAP<STRING,STRING>, info STRUCT<country:String,province:String,shi:String> ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' COLLECTION ITEMS TERMINATED BY ',' MAP KEYS TERMINATED BY ':' LINES TERMINATED BY '\n' LOCATION "/test";//可以設定源資料的位置,若不設定預設就在Hive的工作目錄區
建表方式二:
  create table gfstbl1 like gfstbl;只是建立表結構
建表方式三:
 create table gfstbl2 AS SELECT id,name,gfs,address from gfstbl; 
  會建立相應的表結構,並且插入資料,相當於完整的賦值
載入資料:
load data local inpath '/root/gfs.txt' into table gfstbl;
查看錶描述資訊:
DESCRIBE [EXTENDED|FORMATTED] table_name
EXTENDED極簡的方式顯示
FORMATTED格式化方式來顯示
DESCRIBE EXTENDED gfstbl;預設就是EXTENDED
DESCRIBE FORMATTED gfstbl;
插入資料的其他方式:
插入資料的方式:
	1insert 新資料
	2load
	3、查詢其他表資料 insert 到新表中
	模板:
		INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] 
		select_statement1 FROM from_statement;
		
		FROM from_statement
		INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) 
		[IF NOT EXISTS]] select_statement1

		insert into rest select count(*) from table;
		
		習慣寫法 from提前  減少SQL程式碼的冗餘
		from day_hour_table
		insert into rest 
			select count(*) ;

2. 外部表

資料儲存位置由使用者自己指定,由HDFS管理,刪除外部表時僅僅會刪除元資料,儲存資料不會受到影響。

建表語句:
create external table wc_external 
   (word1 STRING, 
   word2 STRING) 
   ROW FORMAT DELIMITED 
   FIELDS TERMINATED BY ' ' 
   location '/test/external'; location可加可不加,不加location預設是在hive的工作目錄區

3. 臨時表

在當前會話期間存在,會話結束後自動銷燬。

建表語句:
create TEMPORARY table ttabc(id Int,name String) 臨時表的宣告週期是一次會話
進入hive shell 建立一張表,關閉shell後,表丟失,臨時表不支援分割槽

4. 分割槽表

將資料按照某個欄位或者關鍵字分成多個子目錄來儲存,防止暴力掃描全表。

靜態分割槽表:
create table day_hour_table (id int, content string) partitioned by (dt int,hour int) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
載入資料:
-- insert單條插入的方式往分割槽表中插入資料:
	insert into day_hour_table partition(dt=9,hour=1) values(1,"a2 bc");
	insert into day_hour_table partition(dt=9,hour=2) values(3,"a2 bc");
	insert into day_hour_table partition(dt=8,hour=1) values(3,"a2 bc");
	insert into day_hour_table partition(dt=8,hour=2) values(3,"a2 bc");
-- load批量插入的方式往分割槽表中插入資料:
	load data local inpath "/root/ceshi" into table day_table partition (dt=10,hour=10);
刪除Hive分割槽表中的分割槽
ALTER TABLE day_table DROP PARTITION (dt=10,hour=10);
建立\新增分割槽
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location']
[, PARTITION partition_spec [LOCATION 'location'], ...];

partition_spec:
	  : (partition_column = partition_col_value, partition_column = partition_col_value, ...) 

-- 建立一個空分割槽:
ALTER TABLE day_hour_table ADD PARTITION (dt=10000, hour=2000);
-- 然後將資料上傳到空分割槽對應的目錄下,分割槽表中就會顯示資料
	HDFS dfs -put ........
-- 建立一個空分割槽並且將空分割槽指向資料位置:
ALTER TABLE day_hour_table ADD PARTITION (dt=10000, hour=2000) location "/test" 
動態分割槽表:

動態分割槽表和靜態分割槽表建表語句相同,插入資料的方式不同

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

動態分割槽可以根據資料本身的特徵自動來劃分分割槽,load data …只是將資料上傳到HDFS指定目錄,所以我們需要使用from insert的方式插入資料hive才會根據分割槽設定自動將資料進行分割槽。

5. 分桶表

將資料按照某個欄位和桶的數量,對指定欄位進行取模運算,拆分成多個小檔案來儲存,模相同的儲存在同一個小檔案中,提高join以及抽樣的效率。

set hive.enforce.bucketing=true;

分桶表是對列值取雜湊值的方式,將不同資料放到不同檔案中儲存 由列的雜湊值除以桶的個數來決定每條資料劃分在哪個桶中 對於hive中每一個表、分割槽都可以進一步進行分桶

建表語句

CREATE TABLE psnbucket( id INT, name STRING, age INT) 
CLUSTERED BY (age) INTO 4 BUCKETS 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

插入資料

insert into table psnbucket select id, name, age from original;

抽樣:

select * from psnbucket tablesample(bucket 1 out of 4 on age);

分桶表+分割槽表:

CREATE TABLE psnbucket_partition( id INT, name STRING, age INT) 
PARTITIONED BY(height DOUBLE) 
CLUSTERED BY (age) INTO 4 BUCKETS 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
插入資料:
insert into table psnbucket_partition partition(height) select id, name,
age,height from original;

多個分割槽中的對應的位置的小檔案組成一個桶

插入資料:

insert into table psnbucket_partition partition(height) select id, name, 
age,height from original;

多個分割槽中的對應的位置的小檔案組成一個桶