Hive基礎知識

1、Hive簡介

什麼是Hive

hive是基於Hadoop的一個數據倉庫工具,能夠將結構化的數據文件映射爲一張數據庫表,並提供簡單的sql查詢功能,能夠將sql語句轉換爲MapReduce任務進行運行。 其優勢是學習成本低,能夠經過類SQL語句快速實現簡單的MapReduce統計,沒必要開發專門的MapReduce應用,十分適合數據倉庫的統計分析。mysql

Hive on Spark 和 Hive on Tezsql

爲何使用Hive

面臨的問題:

  • 人員學習成本過高
  • 項目週期要求過短 我只是須要一個簡單的環境 MapReduce 如何搞定 複雜查詢好難
  • Join如何實現

爲何要使用Hive:

  • 操做接口採用類SQL語法,提供快速開發的能力
  • 避免了去寫MapReduce,減小開發人員的學習成本
  • 擴展功能很方便

2、Hive結構

Hive 的結構如圖所示
Hive結構圖
主要分爲如下幾個部分:shell

  • 用戶接口–包括 CLI,Client,WUI。
  • 元數據存儲–一般是存儲在關係數據庫如 mysql, derby 中。可經過hive-default.xml修改
  • 解釋器–編譯器、優化器、執行器。
  • Hadoop–用 HDFS 進行存儲,利用 MapReduce 進行計算。

3、Hive支持的格式

支持的基本類型有數據庫

數據類型 所佔字節 開始支持版本
TINYINT 1byte,-128 ~ 127
SMALLINT 2byte,-32,768 ~ 32,767
INT 4byte,-2,147,483,648 ~ 2,147,483,647
BIGINT 8byte,-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
BOOLEAN
FLOAT 4byte單精度
DOUBLE 8byte雙精度
STRING
BINARY 從Hive0.8.0開始支持
TIMESTAMP 從Hive0.8.0開始支持
DECIMAL 從Hive0.11.0開始支持
CHAR 從Hive0.13.0開始支持
VARCHAR 從Hive0.12.0開始支持
DATE 從Hive0.12.0開始支持
ARRAY ARRAY類型是由一系列相同數據類型的元素組成,這些元素能夠經過下標來訪問。好比有一個ARRAY類型的變量fruits,它是由['apple','orange','mango']組成,那麼咱們能夠經過fruits[1]來訪問元素orange,由於ARRAY類型的下標是從0開始的;
MAP MAP包含key->value鍵值對,能夠經過key來訪問元素。好比」userlist」是一個map類型,其中username是key,password是value;那麼咱們能夠經過userlist['username']來獲得這個用戶對應的password;
STRUCT STRUCT能夠包含不一樣數據類型的元素。這些元素能夠經過」點語法」的方式來獲得所須要的元素,好比user是一個STRUCT類型,那麼能夠經過user.address獲得這個用戶的地址。
UNION UNIONTYPE,他是從Hive 0.7.0開始支持的。

建立一個複合類型的表apache

 
 
 
 
 
CREATE TABLE employees ( name STRING, salary FLOAT, subordinates ARRAY<STRING>, deductions MAP<STRING, FLOAT>, address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>) PARTITIONED BY (country STRING, state STRING)

建立數據庫
CREATE DATABASE [IF NOT EXISTS] userdb
刪除數據庫
DROP DATABASE [IF EXISTS ]userdb數組

4、表的操做

建立表

  • 內部表與外部表
類型 內部表 外部表
數據來源 與數據庫中的 Table 在概念上是相似 指向已經在 HDFS 中存在的數據,能夠建立 Partition
數據存放 每個 Table 在 Hive 中都有一個相應的目錄存儲數據。例如,一個表 test,它在 HDFS 中的路徑爲:/ warehouse/test。 warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的數據倉庫的目錄 它和 內部表 在元數據的組織上是相同的,而實際數據的存儲則有較大的差別,能夠存放於各個不一樣的目錄
數據處理 全部的 Table 數據都保存在這個目錄中,內部表的建立過程和數據加載過程(這兩個過程能夠在同一個語句中完成),在加載數據的過程當中,實際數據會被移動到數據倉庫目錄中 ,以後對數據訪問將會直接在數據倉庫目錄中完成。 刪除表時,表中的數據和元數據將會被同時刪除 外部表 只有一個過程,加載數據和建立表同時完成,並不會移動到數據倉庫目錄中,只是與外部數據創建一個連接。當刪除一個外部表時,僅刪除該連接

內部表:緩存

 
 
 
 
 
CREATE TABLE [IF NOT EXISTS] worker1(id INT,name STRING)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ',' --列分隔符LINES TERMINATED BY '\n' --行分隔符STORED AS ORC --存儲格式,支持TextFileParquetRCFileORC FileLOCATION '/user/hive/test/worker1'--數據存放路徑

外部表:app

 
 
 
 
 
CREATE EXTERNAL TABLE [IF NOT EXISTS] worker2(id INT,name STRING)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ',' --列分隔符LINES TERMINATED BY '\n' --行分隔符STORED AS ORC --存儲格式,支持TextFileParquetRCFileORC FileLOCATION '/user/hive/test/worker2'--數據存放路徑

內部表與外部表相互轉換yii

 
 
 
 
 
alter table worker1 set TBLPROPERTIES ('EXTERNAL'='TRUE'); --內部錶轉外部表 alter table worker1 set TBLPROPERTIES ('EXTERNAL'='FALSE'); --外部錶轉內部表

動態建立表
動態建立表一般會用在建立臨時表,又不想使用緩存(固然,hive不支持緩存,SparkSQL中支持)的狀況
不修改字段名與類型:ide

 
 
 
 
 
CREATE TABLE worker_tempSTORED AS orcAS SELECT * FROM worker2

刪除表

DROP TABLE [IF EXISTS] table_name

若是是外部表,而且有location,則須要經過hdfs刪除對應的目錄才能徹底刪除數據

清空表

 
 
 
 
 
TRUNCATE TABLE table_name;

修改表

  • 1.修改表名
    下面是查詢重命名錶,把 employee 修改成 emp
    ALTER TABLE employee RENAME TO emp;
    如:
 
 
 
 
 
hive> ALTER TABLE worker1 RENAME TO worker;OKTime taken: 1.156 secondshive> show tables;OKworkerworker2

修改字段名與字段類型

下表包含employee表的字段,它顯示的字段要被更改(粗體)。

字段名 從數據類型轉換 更改字段名稱 轉換爲數據類型
eid int eid int
name String ename String
salary Float salary Double
designation String designation String

下面查詢重命名使用上述數據的列名和列數據類型:

修改字段名
ALTER TABLE employee CHANGE name ename String
如:

 
 
 
 
 
hive> ALTER TABLE worker1 CHANGE name ename StringOKTime taken: 0.398 secondshive> desc worker1;OKid intename string

修改字段類型
ALTER TABLE employee CHANGE salary salary Double
如:

 
 
 
 
 
hive> ALTER TABLE worker1 CHANGE ename name varchar(20);OKTime taken: 0.472 secondshive> desc worker1;OKid int name varchar(20)

增長列

 
 
 
 
 
ALTER TABLE employee ADD COLUMNS ( dept STRING COMMENT 'Department name',--COMMENT增長註釋test String)

 
 
 
 
 
hive> ALTER TABLE worker1 ADD COLUMNS ( > dept STRING > );OKTime taken: 0.372 secondshive> desc worker1;OKid int name varchar(20) dept string Time taken: 0.309 seconds, Fetched: 3 row(s)

修改列的順序

這個功能一般和增長列的功能一塊兒用。
由於Hive增長列只能在最後的一個Column後面增長,假如我想在中間插入一列怎麼辦呢?
可使用

 
 
 
 
 
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

因爲hive文件並無修改,只是至關於修改了字段名字而已,數據並無相應的移動。

所以,此方法適用於已建表,後續會從新刷新數據的狀況;或者空表。

刪除列

目前貌似移除了這個功能

ALTER TABLE worker1 DROP COLUMN test1

替換表

 
 
 
 
 
ALTER TABLE worker1 REPLACE COLUMNS ( id INT, name String);

上面這條sql執行失敗,提示 SerDe may be incompatible

修改字段順序

ALTER TABLE worker1 CHANGE COLUMN c c string AFTER a;

其餘操做

查看錶信息

desc worker1

查看建表信息

show create table worker1

查看格式信息

desc formatted worker1

改變表文件格式

ALTER TABLE worker1 SET FILEFORMAT textFile

查看函數

show functions

5、數據操做

1.插入數據

Hive不支持單句插入的語句,必須批量,因此不要期望能用insert into workers values (1,'jack') 這樣的語句插入數據。hive支持的插入數據的方式有兩種:

  • 從文件讀取數據
  • 從別的表讀出數據插入(insert from select)

從文件讀取數據

先創建一個叫 worker.csv的文件,內容爲

 
 
 
 
 
1,jack2,terry3,michael

使用LOAD DATA 導入到Hive的表中

 
 
 
 
 
LOAD DATA LOCAL INPATH '/home/root/workers.csv' INTO TABLE workers1;
  • 不要少了 LOCAL 關鍵字,LOAD DATA LOCAL INPATHLOAD DATA INPATH 的區別是一個是從你本地磁盤上找源文件,一個是從hdfs上找文件
  • 若是加上OVERWRITE能夠再導入以前先清空表,好比 LOAD DATA LOCAL INPATH '/home/root/workers.csv' OVERWRITE INTO TABLE workers1;

從其餘結果集插入

 
 
 
 
 
INSERT [OVERWRITE] INTO TABLE works2select * from test

若是有分區(稍後咱們會講到)

 
 
 
 
 
INSERT INTO [OVERWRITE] TABLE table_name1 PARTITION(partition_name1 data, partition_name2 data, )SELECT select_statement FROM from_statement;

2.分區和分桶

分區表是用來加速查詢的,好比你的數據很是多,可是你的應用場景是基於這些數據作日報表,那你就能夠根據日進行分區,當你要作2014-05-05的報表的時候只須要加載2014-05-05這一天的數據就好了。

建立分區表

 
 
 
 
 
DROP TABLE IF EXISTS employee;CREATE EXTERNAL TABLE IF NOT EXISTS employee(id INT,name STRING,dept String,year int)PARTITIONED BY(p_year int)--指定分區,能夠包含多級分區ROW FORMAT DELIMITEDFIELDS TERMINATED BY ',' --列分隔符LINES TERMINATED BY '\n' --行分隔符STORED AS textFile --存儲格式,支持TextFileParquetRCFileORC FileLOCATION '/user/hive/test/employeedata'--數據存放路徑

查看分區

  • 查看全部分區
    SHOW PARTITIONS employee;
  • 查看分區的全部信息
    DESC FORMATTED table_name partition (month = ‘2015-01’ , day = '2015-01-25′)

插入分區數據

 
 
 
 
 
INSERT INTO TABLE table_name PARTITION PARTITION(p_column = ...)SELECT * FROM other_table_name;
 
 
 
 
 
INSERT OVERWRITE TABLE table_name PARTITION PARTITION(p_column = ...)SELECT * FROM other_table_name;

添加分區

 
 
 
 
 
ALTER TABLE table_name ADD [IF NOT EXISTS ] PARTITION(p_column = ...) LOCATION "/user/root/test"

如:

 
 
 
 
 
ALTER TABLE employee ADD IF NOT EXISTS PARTITION(p_year = 2012) LOCATION "/user/hive/test/employeedata/2012";ALTER TABLE employee ADD IF NOT EXISTS PARTITION(p_year = 2013) LOCATION "/user/hive/test/employeedata/2013";

重命名分區

 
 
 
 
 
ALTER TABLE table_name PARTITION (p_date="2015-12-12") RENAME TO PARTITION (p_date="2015-12-13");

刪除分區

 
 
 
 
 
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec, PARTITION partition_spec,...;

分區使用

在hive中能夠直接使用分區進行查詢和計算操做,因爲加入了分區,使得hive處理數據時能夠讀取指定分區的內容,而不用遍歷全表,所以極大的加快了查詢速度
如:

 
 
 
 
 
select * from employee where p_year = 2013;結果:+--------------+----------------+----------------+----------------+------------------+--+| employee.id | employee.name | employee.dept | employee.year | employee.p_year |+--------------+----------------+----------------+----------------+------------------+--+| 3 | kaleel | SC | 2013 | 2013 || 4 | Prasanth | SC | 2013 | 2013 |+--------------+----------------+----------------+----------------+------------------+--+

分桶

桶表是根據某個字段的hash值,來將數據扔到不一樣的「桶」裏面。外國人有個習慣,就是分類東西的時候擺幾個桶,上面貼不一樣的標籤,因此他們取名的時候把這種表形象的取名爲桶表。桶表表專門用於採樣分析

把表(或者分區)組織成桶(Bucket)有兩個理由:

(1)得到更高的查詢處理效率。桶爲表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,鏈接兩個在(包含鏈接列的)相同列上劃分了桶的表,可使用 Map 端鏈接 (Map-side join)高效的實現。好比JOIN操做。對於JOIN操做兩個表有一個相同的列,若是對這兩個表都進行了桶操做。那麼將保存相同列值的桶進行JOIN操做就能夠,能夠大大較少JOIN的數據量。

(2)使取樣(sampling)更高效。在處理大規模數據集時,在開發和修改查詢的階段,若是能在數據集的一小部分數據上試運行查詢,會帶來不少方便。

 
 
 
 
 
CREATE TABLE b_student(id INT, name STRING)PARTITIONED BY(dt STRING, country STRING)CLUSTERED BY(id) --按照哪一個字段分桶SORTED BY(name) INTO 4 BUCKETS --分紅幾個桶 row format delimited fields TERMINATED BY ',';

6、複合類型

Array

建立

 
 
 
 
 
Arraycreate table login_array(ip string,uid array<bigint>)partitioned by (dt string)row format delemited fields terminated by ','--列分隔符collection items terminated by '|' --數組分隔符stored as textfile;

使用

 
 
 
 
 
select ip uid[0] from login_array where dt='20130101';--使用數組下標訪問select ip,size(uid) from login_array where dt='20130101';--查看數組長度select * from login_array where array_contains(uid,'31050007');--查找數組

Map

建立

 
 
 
 
 
Map:create table map_test_raw(ip string,request Map<string,string>)row format delemited fields terminated by ',' --列分隔符collection items terminated by '|' --Map集合分隔符map keys terminated by '=' --Keyvalue分隔符stored as textfile;

使用

 
 
 
 
 
select request['src'] from map_test_raw;

7、建立視圖和索引以及數據緩存

視圖

根據用戶的需求建立視圖。能夠將任何結果集數據保存爲一個視圖。視圖在Hive的用法和SQL視圖用法相同。它是一個標準的RDBMS概念。咱們能夠在視圖上執行全部DML操做。

建立視圖

 
 
 
 
 
CREATE VIEW worker_view ASSELECT * FROM worker2WHERE id>2;

刪除視圖

DROP VIEW worker_view

索引

索引也不過是一個表上的一個特定列的指針。建立索引意味着建立一個表上的一個特定列的指針。

建立索引

 
 
 
 
 
CREATE INDEX worker_index ON TABLE worker2(id)AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'WITH DEFERRED REBUILD

查看索引

SHOW INDEX ON worker2;

刪除索引

DROP INDEX worker_index ON worker2;

緩存

除了視圖之外,還可使用數據緩存的方式來保存某一結果集,只不過視圖是將結果集保存在hive中,使用的時候仍舊運行了一次查詢。而緩存則是將數據保存在了內存中,一般適用於須要屢次使用的數據查詢;可是,cache table的語法只能在Spark SQl中使用

建立緩存表

整表緩存
sql=CACHE TABLE cache_worker AS SELECT * FROM worker2
DataFrame=hiveCtx.cacheTable("worker2")
hiveCtx.sql("SELECT * FROM worker2").cache()[或.persist()]
緩存部分數據
sql=CACHE TABLE cache_worker AS SELECT * FROM worker2 where id>1
DataFrame=hiveCtx.sql("SELECT * FROM worker2 where id>1").cache()[或.persist()]
該條語句對應了

刪除緩存表

sql=DROP TABLE cache_worker
DataFrame=hiveCtx.uncacheTable(cache_worker)dataframe.unpersist()

參考連接Hive教程

相關文章
相關標籤/搜索