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;

多個分區中的對應的位置的小文件組成一個桶

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章