Hive - DDL & DML

HiveSQL DDL

  HiveSQL中的DDL語言是對Hive表數據結構的操作,比如創建、修改、刪除一張表。
  Hive是構建在HDFS之上的,Hive的數據存放於HDFS之中,HDFS存儲的是文件,怎麼對應結構化數據,這就要求Hive必須要有存放元數據信息的Meta表,這個可以存放在RDBMS中。

Hive與RDBMS中存儲結構的對比

  Hive中的存儲結構其實就是DHFS的存儲格式

RDBMS Hive
數據庫database HDFS上頂層文件夾
表table 對應Database所指向的目錄
分區Partition table文件夾下
塊bucket 對應以及具體的文件

Hive數據庫Database

  Hive數據庫就是HDFS上頂層的文件夾。

所有的操作都在hive CLI中進行
1、創建一個數據庫叫hive001
  create database hive001;
2、查看數據庫
  show databases;
3、詳細顯示數據庫描述
  desc database hive001; 
4、顯示HDFS上用戶信息
  desc database extended hive001;

  通過上面的show顯示,會發現確實有hive001,但是也有個default,這個default是hive創建完就有的。
  那hive001這個數據庫到底在HDFS上哪裏?!在HDFS上有一個叫做 /user/hive/warehouse/hive001.db 目錄,這個是目錄,雖然.db結尾。所以Hive上手工創建數據庫的數據庫存放在HDFS上的 /user/hive/warehouse/ < databasename >.db上。但是這個數據庫沒有default數據庫。Hive的default數據庫存放路徑其實就是/user/hive/warehouse,這個數據庫比較特殊。

具體創建語法
  CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
  [COMMENT database_comment]
  [LOCATION hdfs_path]
  [WITH DBPROPERTIES (property_name=property_value, ...)];
刪除一個數據庫
  DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

Hive數據表table

  Hive數據表是建立在數據庫基礎上的,所以對應的存放也是在HDFS目錄之下。

選擇一個數據庫
  use hive001;
創建一個數據表
  create table test(id int);
從別的表複製一份表結構
  CREATE table test1 like test;
查看一張表明細
  desc formatted test;
查看錶的創建語句
  show create table test;

  Hive創建完數據表後,我們查看下HDFS,發現確實在對應hive001數據庫所在的HDFS目錄下有一個test目錄(/user/hive/warehouse/hive001.db/test)。

相對完整創建表:
  CREATE TABLE person
  (id int comment 'this is id', name string comment 'this id name' )
  comment 'this is person'
  ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' ;
如果要完整的創建語法,則需要看官網

  Hive中創建一張表,創建表默認使用的是MANAGED_TABLE:內部表。內部表的在drop的時候會刪除HDFS上的文件和Meta上的結構也會刪除。而外部表只刪除meta上的信息,HDFS上的數據還是保留。

外部表定義
create EXTERNAL table test_external 
(empno int, ename string, job string, mgr int, hiredate string, salary double, comm double, deptno int)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t';    

Hive數據表table 常用的數據類型

常用的數據類型 Hive
數值 int bigint float double
字符串 String
時間 date timestamp

  Hive基本上使用的只要使用數值的和字符串,因爲畢竟存儲到文件,一旦轉化成時間出錯,那個記錄就被丟掉,所以直接存String就好了。

Hive數據表DML語言 - 導入數據

  Hive的DML語言是對數據的操作,當然從本地導入數據也是DML語言之一。

1、從本地導入數據到Hive倉庫,當然行和列的分割方式要符合Hive製表的時候的方式
LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' OVERWRITE INTO TABLE person; 
2、或者從Hive上的別的表載入數據
INSERT OVERWRITE TABLE person1
select * FROM person;

Hive數據表DML語言 - Select

  Hive的的DML的Select語法和SQL中的Select的寫法相似,但普通的Select並不會觸發底層MapReduce作業,但是如果Select使用聚合函數(sum、count、max、min、avg等)這個時候會觸發底層的MapReduce。那還有哪些會觸發呢,聚合函數(sum、count、max、min、avg)、分組(group by 、having)、關聯(Join)。
  Hive中有一個case when then語法(不會觸發MR操作)。

select ename,salary,
case 
when salary>1 and salary<=1000 then 'lower'
when salary>1000 and salary<=2000 then 'middle'
when salary>2000 and salary<=4000 then 'high'
else 'highest'
end
from ruozedata_emp;

Hive數據表分區表

  分區表存在的意義就是分數據段查詢時較少IO壓力。比如,你的日誌數據每天放在一個分區內,如果你要查什麼數據,只需要指定分區查找就可以了,沒有必要全表查找。Hive分區表分爲:靜態分區,動態分區。

靜態分區

  在定義表的時候定義分區字段。比如:

按照訂單的月份進行分區
  create table order_partition(
  ordernumber string,
  eventtime string
  )
  partitioned by (event_month string)
  row format delimited fields terminated by '\t';
查看分區
  show partitions order_partition;

  好了表創建好了,下面需要導入數據,load的語法

把數據導入到哪個分區
  LOAD DATA LOCAL INPATH '/home/hadoop/data/order.txt' 
  OVERWRITE INTO TABLE order_partition 
  PARTITION(event_month='2014-05'); 
或者
  insert overwrite table order_partition 
  partition(event_month='2014-08')
  select * from order_4_partition;

  這個時候會出錯,出錯後去 /tmp/$(username)/hive.log中查看下原因,發現還是和原來初始化部署hive一樣的問題。

進入mysql,找到對應數據庫,然後修改字符集
alter table PARTITIONS convert to character set latin1;
alter table PARTITION_KEYS convert to character set latin1;

  這裏有一個很有趣的問題,如果Hive上的數據庫數據都是在HDFS上,如果不用Load也可以直接將數據文件直接放到對應HDFS文件夾下,在查詢表時也能查出新增的數據。但是但是但是,如果按照HDFS中Hive分區的目錄規則創建一個新的分區目錄,插入數據,可是Hive中查詢不到新的數據,因爲這些數據Hive是不認的。因爲MySQl中mate沒有註冊過這個分區。

想要解決HDFS上添加分區在Hive中不認的問題,只需要:
   MSCK REPAIR TABLE order_partition 
或者
   ALTER TABLE order_partition ADD IF NOT EXISTS PARTITION (event_month='2014-07') ;
就會刷新進Hive Meta。
但是第一種方式太暴力了,他會將所有信息會寫到Meta表,性能上消耗太多。推薦使用第二種。

動態分區

  動態分區與靜態分區的區別:創建靜態表插入數據的時候必須要指明分區,這就麻煩了,麻煩在於要是該字段有1000多種值,那就麻煩了。動態分區就不需要指定值。

動態分區創建數據表語法和靜態的一模一樣
  create table ruozedata_dynamic_emp 
  (empno int, ename string, job string, mgr int, hiredate string,   salary double, comm double)
  PARTITIONED by(deptno string)
  ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' ;

區別在於插入數據的時候
動態分區明確要求:分區字段寫在select的最後面   
  insert into table ruozedata_dynamic_emp partition(deptno)
  select empno,ename,job,mgr,hiredate,salary,comm,deptno from   ruozedata_emp ;
這種方式是非嚴格動態分區寫法,一般Hive是嚴格模式,可以關閉,否者上訴的插入會報錯
  set hive.exec.dynamic.partition.mode=nonstrict;

擴展

Hive CLI的參數設置

  Hive在CLI命令行的參數設置採用嚴格的key=value格式

設置只能當前窗口有效,除非寫入到hive-site.sh中
set key=value; 設置    
set key;       取值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章