Hive從入門到放棄

1 Hive基本概念

1.1 什麼是Hive

Hive:由Facebook開源用於解決海量結構化日誌的數據統計。Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張表,並提供類SQL查詢功能。
本質是:將HQL轉化成MapReduce程序,執行流程如下:
HQL執行流程

  • 1)Hive處理的數據存儲在HDFS
  • 2)Hive分析數據底層的實現是MapReduce
  • 3)執行程序運行在Yarn上

1.2 Hive的優缺點

1.2.1 優點

  1. 操作接口採用類SQL語法,提供快速開發的能力(簡單、容易上手)。
  2. 避免了去寫MapReduce,減少開發人員的學習成本。
  3. Hive的執行延遲比較高,因此Hive常用於數據分析,對實時性要求不高的場合。
  4. Hive優勢在於處理大數據,對於處理小數據沒有優勢,因爲Hive的執行延遲比較高。
  5. Hive支持用戶自定義函數,用戶可以根據自己的需求來實現自己的函數。

1.2.2 缺點

  1. Hive的HQL表達能力有限
    (1)迭代式算法無法表達
    (2)數據挖掘方面不擅長
  2. Hive的效率比較低
    (1)Hive自動生成的MapReduce作業,通常情況下不夠智能化
    (2)Hive調優比較困難,粒度較粗

1.3 Hive架構原理

Hive通過給用戶提供的一系列交互接口,接收到用戶的指令(SQL),使用自己的Driver,結合元數據(MetaStore),將這些指令翻譯成MapReduce,提交到Hadoop中執行,最後,將執行返回的結果輸出到用戶交互接口。
hive架構圖

  1. Client:用戶接口,提供CLI(hive shell)、JDBC/ODBC(java訪問hive)、WEBUI(瀏覽器訪問hive)
  2. Metastore:元數據,包括表名、表所屬的數據庫(默認是default)、表的擁有者、列/分區字段、表的類型(是否是外部表)、表的數據所在目錄等;默認存儲在自帶的derby數據庫中,推薦使用MySQL存儲Metastore
  3. Hadoop:使用HDFS進行存儲,使用MapReduce進行計算。
  4. Driver:驅動器
    (1)解析器(SQL Parser):將SQL字符串轉換成抽象語法樹AST,這一步一般都用第三方工具庫完成,比如antlr;對AST進行語法分析,比如表是否存在、字段是否存在、SQL語義是否有誤。
    (2)編譯器(Physical Plan):將AST編譯生成邏輯執行計劃。
    (3)優化器(Query Optimizer):對邏輯執行計劃進行優化。
    (4)執行器(Execution):把邏輯執行計劃轉換成可以運行的物理計劃。對於Hive來說,就是MR/Spark。

1.4 Hive和數據庫對比

由於 Hive 採用了類似SQL 的查詢語言 HQL(Hive Query Language),因此很容易將 Hive 理解爲數據庫。其實從結構上來看,Hive 和數據庫除了擁有類似的查詢語言,再無類似之處。本文將從多個方面來闡述 Hive 和數據庫的差異。數據庫可以用在 Online 的應用中,但是Hive 是爲數據倉庫而設計的,清楚這一點,有助於從應用角度理解 Hive 的特性

1.4.1 查詢語言

由於SQL被廣泛的應用在數據倉庫中,因此,專門針對Hive的特性設計了類SQL的查詢語言HQL。熟悉SQL開發的開發者可以很方便的使用Hive進行開發。

1.4.2 數據存儲位置

Hive 是建立在 Hadoop 之上的,所有 Hive 的數據都是存儲在 HDFS 中的。而數據庫則可以將數據保存在塊設備或者本地文件系統中。

1.4.3 數據更新

由於Hive是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。因此,Hive中不支持對數據的改寫和添加,所有的數據都是在加載的時候確定好的。而數據庫中的數據通常是需要經常進行修改的,因此可以使用 INSERT INTO … VALUES 添加數據,使用 UPDATE … SET修改數據。

1.4.4 索引

Hive在加載數據的過程中不會對數據進行任何處理,甚至不會對數據進行掃描,因此也沒有對數據中的某些Key建立索引。Hive要訪問數據中滿足條件的特定值時,需要暴力掃描整個數據,因此訪問延遲較高。由於 MapReduce 的引入, Hive 可以並行訪問數據,因此即使沒有索引,對於大數據量的訪問,Hive 仍然可以體現出優勢。數據庫中,通常會針對一個或者幾個列建立索引,因此對於少量的特定條件的數據的訪問,數據庫可以有很高的效率,較低的延遲。由於數據的訪問延遲較高,決定了 Hive 不適合在線數據查詢。

1.4.5 執行

Hive中大多數查詢的執行是通過 Hadoop 提供的 MapReduce 來實現的。而數據庫通常有自己的執行引擎。

1.4.6 執行延遲

Hive 在查詢數據的時候,由於沒有索引,需要掃描整個表,因此延遲較高。另外一個導致 Hive 執行延遲高的因素是 MapReduce框架。由於MapReduce 本身具有較高的延遲,因此在利用MapReduce 執行Hive查詢時,也會有較高的延遲。相對的,數據庫的執行延遲較低。當然,這個低是有條件的,即數據規模較小,當數據規模大到超過數據庫的處理能力的時候,Hive的並行計算顯然能體現出優勢。

1.4.7 可擴展性

由於Hive是建立在Hadoop之上的,因此Hive的可擴展性是和Hadoop的可擴展性是一致的(世界上最大的Hadoop 集羣在 Yahoo!,2009年的規模在4000 臺節點左右)。而數據庫由於 ACID 語義的嚴格限制,擴展行非常有限。目前最先進的並行數據庫 Oracle 在理論上的擴展能力也只有100臺左右。

1.4.8 數據規模

由於Hive建立在集羣上並可以利用MapReduce進行並行計算,因此可以支持很大規模的數據;對應的,數據庫可以支持的數據規模較小。

2 Hive安裝

2.1 安裝地址

  1. Hive官網地址
  2. 文檔查看地址
  3. 下載地址
  4. github地址

2.2 Hive安裝部署

1.解壓apache-hive-1.2.2-bin.tar.gz

[root@iZnq8v4wpstsagZ software]# tar -zxvf apache-hive-1.2.2-bin.tar.gz -C /opt/module

2.修改/opt/module/apache-hive-1.2.2-bin/conf目錄下hive-env.sh.template名稱爲hive-env.sh

[root@iZnq8v4wpstsagZ conf]# mv hive-env.sh.template hive-env.sh

3.配置hive-env.sh文件

[root@iZnq8v4wpstsagZ conf]# vim hive-env.sh

# Set HADOOP_HOME to point to a specific hadoop install directory
HADOOP_HOME=/opt/module/hadoop-2.7.7

# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/opt/module/apache-hive-1.2.2-bin/conf

4.hadoop集羣配置

#在HDFS上創建/tmp和/user/hive/warehouse兩個目錄並修改他們的同組權限可寫
[root@iZnq8v4wpstsagZ hadoop-2.7.7]$ bin/hadoop fs -mkdir /tmp
[root@iZnq8v4wpstsagZ hadoop-2.7.7]$ bin/hadoop fs -mkdir -p /user/hive/warehouse

[root@iZnq8v4wpstsagZ hadoop-2.7.7]$ bin/hadoop fs -chmod g+w /tmp
[root@iZnq8v4wpstsagZ hadoop-2.7.7]$ bin/hadoop fs -chmod g+w /user/hive/warehouse

2.3 MySQL安裝(不需要可跳過)

Hive默認使用採用自帶的derby數據庫存儲Metastore,內嵌的derby數據庫僅支持單連接,推薦使用MySQL存儲Metastore。

  1. MySQL的安裝可參見MySQL筆記
  2. 將mysql驅動程序copy到/opt/module/apache-hive-1.2.2-bin/lib/目錄下
  3. 配置metastore存儲到MySQL
    	[root@iZnq8v4wpstsagZ conf]# touch hive-site.xml
    	[root@iZnq8v4wpstsagZ conf]# vim hive-site.xml
    
    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    <configuration>
    	<property>
    	  <name>javax.jdo.option.ConnectionURL</name>
    	  <value>jdbc:mysql://localhost:3306/metastore?createDatabaseIfNotExist=true</value>
    	  <description>JDBC connect string for a JDBC metastore</description>
    	</property>
    
    	<property>
    	  <name>javax.jdo.option.ConnectionDriverName</name>
    	  <value>com.mysql.jdbc.Driver</value>
    	  <description>Driver class name for a JDBC metastore</description>
    	</property>
    	<!--用戶名-->
    	<property>
    	  <name>javax.jdo.option.ConnectionUserName</name>
    	  <value>root</value>
    	  <description>username to use against metastore database</description>
    	</property>
    	<!--密碼-->
    	<property>
    	  <name>javax.jdo.option.ConnectionPassword</name>
    	  <value>000000</value>
    	  <description>password to use against metastore database</description>
    	</property>
    </configuration>
    

2.4 Hive數據訪問

2.4.1 Hive客戶端訪問

[root@iZnq8v4wpstsagZ bin]# hive

2.4.2 HiveJDBC訪問

#啓動hive服務端
[root@iZnq8v4wpstsagZ bin]# hiveserver2 

#另開一個窗口使用jdbc訪問,連接成功服務端返回OK
[root@iZnq8v4wpstsagZ bin]# beeline 
Beeline version 1.2.2 by Apache Hive
beeline> !connect jdbc:hive2://localhost:10000
Connecting to jdbc:hive2://localhost:10000
Enter username for jdbc:hive2://localhost:10000: root
Enter password for jdbc:hive2://localhost:10000: (回車即可)
Connected to: Apache Hive (version 1.2.2)
Driver: Hive JDBC (version 1.2.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://localhost:10000> show databases;
+----------------+--+
| database_name  |
+----------------+--+
| default        |
| test_db        |
| test_db1       |
+----------------+--+
3 rows selected (1.246 seconds)

2.5 Hive基本操作

2.5.1 Hive常用交互命令

[root@iZnq8v4wpstsagZ bin]# hive -help
usage: hive
 -d,--define <key=value>          Variable subsitution to apply to hive
                                  commands. e.g. -d A=B or --define A=B
    --database <databasename>     Specify the database to use
 -e <quoted-query-string>         SQL from command line
 -f <filename>                    SQL from files
 -H,--help                        Print help information
    --hiveconf <property=value>   Use value for given property
    --hivevar <key=value>         Variable subsitution to apply to hive
                                  commands. e.g. --hivevar A=B
 -i <filename>                    Initialization SQL file
 -S,--silent                      Silent mode in interactive shell
 -v,--verbose                     Verbose mode (echo executed SQL to the
                                  console)

–database:指定數據庫
-e:不進入hive的交互窗口執行SQL語句
-f:用於執行SQL文件

2.5.2 Hive其他命令操作

1.退出cli

hive> exit;
#或
hive> quit;

在新版的hive中沒區別了,在以前的版本是有的:
exit:先隱性提交數據,再退出;
quit:不提交數據,退出;

2.在hive cli命令窗口中如何查看hdfs文件系統

hive> dfs -ls /;

3.在hive cli命令窗口中執行本地文件系統命令

hive> !ls /opt/module/datas;

4.查看在hive中輸入的所有歷史命令

#進入當前用戶的家目錄
[root@iZnq8v4wpstsagZ bin]# cat /root/.hivehistory 

2.6 Hive常見屬性配置

2.6.1 Hive數據倉庫位置配置

<property>
	<name>hive.metastore.warehouse.dir</name>
	<value>/user/hive/warehouse</value>
	<description>location of default database for the warehouse</description>
</property>
  1. default數據倉庫的最原始位置是在hdfs上的:/user/hive/warehouse路徑下。
  2. 在倉庫目錄下,沒有對默認的數據庫default創建文件夾。如果某張表屬於default數據庫,直接在數據倉庫目錄下創建一個文件夾。
  3. 修改default數據倉庫原始位置(將上述配置信息拷貝到hive-site.xml文件中修改)。

2.6.2 查詢後信息顯示配置

在hive-site.xml文件中添加如下配置信息,就可以實現顯示當前數據庫,以及查詢表的頭信息配置

<!--查詢顯示錶頭信息-->
<property>
	<name>hive.cli.print.header</name>
	<value>true</value>
</property>
<!--顯示當前數據-->
<property>
	<name>hive.cli.print.current.db</name>
	<value>true</value>
</property>

2.6.3 Hive運行日誌信息配置

Hive的日誌配置文件在/opt/module/apache-hive-1.2.2-bin/conf/目錄下,修改/opt/module/hive/conf/hive-log4j.properties.template文件名稱爲hive-log4j.properties。
日誌存放目錄爲:

#/tmp/root
hive.log.dir=${java.io.tmpdir}/${user.name}

可修改該參數更改存放位置。

2.6.4 參數配置方式

查看當前所有的配置信息或某個參數配置

hive (default)> set;
hive (default)> set mapred.reduce.tasks;

1)配置文件:
默認配置文件:hive-default.xml
用戶自定義配置文件:hive-site.xml
2)命令行參數方式啓動hive(僅對本次hive啓動有效):

[root@iZnq8v4wpstsagZ bin]# hive -hiveconf mapred.reduce.tasks=10;

3)參數聲明方式(僅對本次hive啓動有效):

hive (default)> set mapred.reduce.tasks=10;

3 Hive數據類型

3.1 基本數據類型

3.1.1 數值類型

Hive數據類型 Java數據類型 說明
TINYINT byte 1byte有符號整數,-128 to 127
SMALINT short 2byte有符號整數,-32,768 to 32,767
INT/INTEGER int 4byte有符號整數,-2,147,483,648 to 2,147,483,647
BIGINT long 8byte有符號整數,-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
FLOAT float 4byte單精度浮點數
DOUBLE double 8byte雙精度浮點數
DECIMAL Decimal Hive 0.11.0開始引入,精度爲38位,Hive 0.13.0引入了用戶自定義的精度和比例
NUMERIC Decimal 類似DECIMAL,開始於Hive 3.0.0

3.1.2 日期時間類型

Hive數據類型 Java數據類型 說明
TIMESTAMP TimeStamp 時間戳yyyy-mm-dd hh:mm:ss[.f…],開始於Hive 0.8.0
DATE java.util.Date 日期yyyy-mm-dd,開始於Hive 0.12.0
INTERVAL - 開始於Hive 1.2.0

3.1.3 字符串類型

Hive數據類型 Java數據類型 說明
STRING string 字符系列,可以指定字符集,可以使用單引號或者雙引號,理論上可存儲2GB
VARCHAR string 長度不定字符串,長度1 - 65535,開始於Hive 0.12.0
CHAR string 長度固定字符串,長度0-255,開始於Hive 0.13.0

3.1.3 其他類型

Hive數據類型 Java數據類型 說明
BOOLEAN boolean 布爾類型,true或者false
BINARY - 字節序列

3.2 集合數據類型

Hive數據類型 Java數據類型 說明
STRUCT 類似C中Struct STRUCT<col_name : data_type[COMMENT col_comment], …>
MAP 類似Map MAP<primitive_type, data_type>,從Hive 0.14開始允許使用負值和非常量表達式
ARRAY 類似Array ARRAY<data_type>,從Hive 0.14開始允許使用負值和非常量表達式
UNIONTYPE - UNIONTYPE<data_type, data_type, …>,開始於Hive 0.7.0

示例:

{
    "name": "songsong",
    "friends": ["bingbing" , "lili"] , //列表Array, 
    "children": {                      //鍵值Map,
        "xiao song": 18 ,
        "xiaoxiao song": 19
    }
    "address": {                       //結構Struct,
        "street": "hui long guan" ,
        "city": "beijing" 
    }
}

1.創建本地文件collection.txt

[root@iZnq8v4wpstsagZ datas]# vim collection.txt 
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

2.創建表

[root@iZnq8v4wpstsagZ datas]# hive
hive (default)> create table collection(
              > name varchar(8),
              > friends array<string>,
              > children map<string,int>,
              > address struct<street:string,city:string>
              > )
              > row format delimited fields terminated by ','		#列分割符
              > collection items terminated by '_'					#集合數據類型分隔符
              > map keys terminated by ':'							#Map中的kv分隔符
              > lines terminated by '\n';							#行分隔符

3.導入collection.txt中數據到數據表collection

hive (default)> load data local inpath '/opt/module/datas/collection.txt' into table collection;

4.查詢

hive (default)> select * from collection where name='songsong';
songsong	["bingbing","lili"]	{"xiao song":18,"xiaoxiao song":19}	{"street":"hui long guan","city":"beijing"}
hive (default)> select name,friends[1],children['xiao song'],address.city from collection where name='songsong';
songsong	lili	18	beijing

3.3 類型轉換

Hive的原子數據類型是可以進行隱式轉換的,類似於Java的類型轉換。

3.3.1 隱式類型轉換

  • 任何整數類型都可以隱式地轉換爲一個範圍更廣的類型,如TINYINT可以轉換成INT,INT可以轉換成BIGINT。
  • 所有整數類型、FLOAT和STRING類型都可以隱式地轉換成DOUBLE。
  • TINYINT、SMALLINT、INT都可以轉換爲FLOAT。
  • BOOLEAN類型不可以轉換爲任何其它的類型。

3.3.2 強制類型轉換

使用CAST可以實現強制類型轉換,如:

CAST('1' AS INT)

如果強制類型轉換失敗則會返回NULL。

4 Data Definition Language

  • CREATE DATABASE/SCHEMA,TABLE,VIEW,FUNCTION,INDEX
  • DROP DATABASE/SCHEMA,TABLE,VIEW,INDEX
  • TRUNCATE TABLE
  • ALTER DATABASE/SCHEMA,TABLE,VIEW
  • MSCK REPAIR TABLE(or ALTER TABLE RECOVER PARTITIONS)
  • SHOW DATABASES/SCHEMAS,TABLES,TBLPROPERTIES,VIEWS,PARTITIONS,FUNCTION,INDEX[ES], COLUMNS, CREATE TABLE
  • DESCRIBE DATABASE/SCHEMA, table_name, view_name, materialized_view_name

partitions除了show partitions table_name,通常都用於table語句的選項。

4.1 數據庫操作

4.1.1 創建數據庫

#創建一個數據庫
hive (default)> create database db_hive
#避免要創建的數據庫已經存在錯誤,增加if not exists判斷
hive (default)> create database if not exists db_hive;
#創建一個數據,指定數據庫在HDFS上的存放位置,默認在/user/hive/warehouse/目錄下創建db_hive_loc.db
hive (default)> create database if not exists db_hive_loc location '/user/hive/warehouse/db_hive_loc.db';

4.1.2 查詢數據庫

#顯示所有數據庫
hive (default)> show databases;
#過濾顯示數據庫
hive (default)> show databases like 'db_hive*';
#顯示數據庫信息
hive (db_hive)> desc database db_hive;
#顯示數據庫詳細信息,extended
hive (default)> desc database extended db_hive;

4.1.2 修改數據庫

用戶可以使用ALTER DATABASE命令爲某個數據庫的DBPROPERTIES設置kv屬性,來描述這個數據庫的屬性信息。數據庫的其他元數據信息都是不可更改的,包括數據庫名和數據庫所在的目錄位置。

#添加數據庫屬性,可通過desc database extended db_hive查看
hive (default)> alter database db_hive set dbproperties('createTime'='20170830','updateTime'='20191012');

4.1.3 刪除數據庫

#刪除空數據庫
hive (default)> drop database if exists db_hive1;
#數據庫不爲空可使用cascade級聯刪除(慎用)
drop database if exists db_hive cascade;

4.2 表操作

4.2.1 創建表

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]

字段分析:

  1. CREATE TABLE創建表,使用IF NOT EXISTS判斷表是否存在,避免異常。
  2. EXTERNAL創建外部表。
  3. COMMENT爲表和列添加註釋。
  4. PARTITIONED BY創建分區表
  5. CLUSTERED BY創建分桶表
  6. SORTED BY排序
  7. ROW FORMAT DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]。SerDe是Serialize/Deserilize的簡稱,目的用於序列化和反序列化。用戶在建表的時候可以自定義SerDe或者使用自帶的SerDe。如果沒有指定ROW FORMAT 或者ROW FORMAT DELIMITED,將會使用自帶的SerDe。在建表的時候,用戶還需要爲表指定列,用戶在指定表的列的同時也會指定自定義的SerDe,Hive通過SerDe確定表的具體的列的數據。
  8. STORED AS指定存儲文件類型,常用的有SEQUENCEFILE(二進制序列文件)、TEXTFILE(文本)、RCFILE(列式存儲格式文件)
  9. LOCATION指定表在HDFS上的存儲位置
  10. LIKE複製現有的表結構,不復制數據

4.2.1.1 管理表

默認創建的表都是所謂的管理表,有時也被稱爲內部表。因爲這種表,Hive會(或多或少地)控制着數據的生命週期。Hive默認情況下會將這些表的數據存儲在由配置項hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定義的目錄的子目錄下。 當我們刪除一個管理表時,Hive也會刪除這個表中數據。管理表不適合和其他工具共享數據。

#普通創建表
hive (default)> create table if not exists student2(
              > id int, 
              > name string
              > )
              > row format delimited fields terminated by '\t'
              > stored as textfile
              > location '/user/hive/warehouse/student2';
#根據查詢結果創建表
hive (default)> create table if not exists student3 as select id, name from student;
#複製表結構
hive (default)> create table if not exists student4 like student;
#查詢表的類型,管理表或外部表
hive (default)> desc formatted student2;

4.2.1.2 外部表

因爲表是外部表,所以Hive並非認爲其完全擁有這份數據。刪除該表並不會刪除掉這份數據,不過描述表的元數據信息會被刪除掉。

#普通創建表
hive (default)> create external table if not exists student3(
              > id int, 
              > name string
              > )
              > row format delimited fields terminated by '\t'
              > stored as textfile
              > location '/user/hive/warehouse/student3';

4.2.1.3 管理表與外部表的互相轉換

#將外部錶轉換爲管理表
hive (default)> alter table student3 set tblproperties('EXTERNAL'='FALSE');
#查看錶詳情
hive (default)> desc formatted student3;

4.2.1.4 分區表

分區表實際上就是對應一個HDFS文件系統上的獨立的文件夾,該文件夾下是該分區所有的數據文件。Hive中的分區就是分目錄,把一個大的數據集根據業務需要分割成小的數據集。在查詢時通過WHERE子句中的表達式選擇查詢所需要的指定的分區,這樣的查詢效率會提高很多。

#創建分區表,根據月份分區
hive (default)> create table dept_partition(
                 > deptno int,
                 > dname string,
                 > loc string
                 > )
                 > partitioned by(month string)
                 > row format delimited fields terminated by '\t';
#加載數據到分區表                 
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table dept_partition partition(month='201910');
#查詢分區表數據
hive (default)> select * from dept_partition where month='201910';

#查看分區表分區
hive (default)> show partitions dept_partition;

#創建單個分區
hive (default)> alter table dept_partition add partition(month='201909');
#創建多個分區
hive (default)> alter table dept_partition add partition(month='201907') partition(month='201908');

#刪除單個分區
hive (default)> alter table dept_partition drop partition (month='201907');
#刪除多個分區,注意逗號分割
hive (default)> alter table dept_partition drop partition (month='201908'), partition (month='201909');

多級分區則會創建多級目錄。

幾種加載數據的方式:
普通表加載數據可以直接通過dfs命令上傳數據文件到表目錄下,分區表與之不同,需要關聯。

1.正常加載數據到分區表:

hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table dept_partition partition(month='201910');

2.把數據直接上傳到HDFS目錄上,讓分區、數據與分區表產生關聯

#創建分區目錄
hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition/month=201912
#上傳數據文件
hive (default)> dfs -put /opt/module/datas/dept.txt  /user/hive/warehouse/dept_partition/month=201912;

#執行修復命令或添加分區,即可查詢到分區和數據
hive (default)> msck repair table dept_partition;
#or
hive (default)> alter table dept_partition add partition(month='201912');

3.創建文件夾後load數據到分區

#創建分區目錄
hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition/month=201901
#加載數據到分區目錄
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table dept_partition partition(month='201901');

4.2.1.5 分桶表

詳見6.1.5 分桶及抽樣查詢

4.2.2 修改表

4.2.2.1 重命名錶

hive (default)> alter table dept rename to dept_normal;

4.2.2.2 增加/修改/刪除表分區

詳見4.2.1.4 分區表

4.2.2.3 增加/修改/替換列信息

更新列語法:ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
增加和替換列語法:ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

#添加列
hive (default)> alter table dept_normal add columns(location string);
#更新列
hive (default)> alter table dept_normal change column loc loc string;
#調整列的順序,將location列放到deptno列後
hive (default)> alter table dept_normal change column location location string after deptno;
#替換表中所有字段,相當於重新定義表字段
hive (default)> alter table dept_normal replace columns(deptno int,dname string,loc string);

4.2.2.4 刪除表

hive (default)> drop table dept_normal;

5 Data Manipulation Language

5.1 數據導入

5.1.1 Load

語法:LOAD DATA [LOCAL] INPATH path_name [OVERWRITE] INTO TABLE table_name [PARTITION (partcol1=val1,…)] [INPUTFORMAT 'inputformat' SERDE 'serde'];

  • LOCAL:表示從本地加載數據到hive表;否則從HDFS加載數據到hive表
  • OVERWRITE:表示覆蓋表中已有數據,否則表示追加
  • PARTITION :表示上傳到指定分區(分區表)
  • INPUTFORMAT :從Hive 3.0開始

5.1.2 Insert

語法:
INSERT INTO|OVERWRITE TABLE table_name [PARTITION (partcol1=val1,…)] VALUES (val1,val2,...),...
INSERT INTO|OVERWRITE table_name [PARTITION (partcol1=val1,…)] SELECT ...

#插入多條數據
hive (default)> insert into table dept_partition partition(month='201910') values(1,'c','luan'),(2,'py','hefei');

#插入查詢結果
hive (default)> insert into table dept_partition partition(month='201907') select deptno,dname,loc from dept_partition where month='201911';

5.1.3 As Select

#根據查詢結果創建表
hive (default)> create table if not exists student3 as select id, name from student;

5.1.4 Location

#指定表加載數據路徑
hive (default)> create table if not exists student5(
              > id int, name string
              > )
              > row format delimited fields terminated by '\t'
              > location '/user/hive/warehouse/student5';
#上傳數據              
hive (default)> dfs -put /opt/module/datas/student.txt /user/hive/warehouse/student5;

5.1.5 Import

hive (default)> import table dept_partition partition(month='201909') from
 '/user/hive/warehouse/export/dept';

5.2 數據導出

5.2.1 Insert

#結果導出到本地目錄(數據未格式化)
hive (default)> insert overwrite local directory '/opt/module/datas/export/dept' select * from dept_partition;
#格式化導出到本地目錄
hive (default)> insert overwrite local directory '/opt/module/datas/export/dept' row format delimited fields terminated by '\t' select * from dept_partition;
#格式化導出到HDFS上
hive (default)> insert overwrite directory '/user/yutao/dept' row format delimited fields terminated by '\t' select * from dept_partition;

5.2.2 Hadoop

hive (default)> dfs -get /user/hive/warehouse/dept_partition/month=201909/000000_0
/opt/module/datas/export/dept_hadoop.txt;

5.2.3 Hive Shell

[root@iZnq8v4wpstsagZ bin]# hive -e 'select * from dept_partition;' > /opt/module/datas/export/dept_hive.txt;

5.2.4 Export

#導出到HDFS上
hive (default)> export table dept_partition to '/user/hive/warehouse/export/dept';

5.2.5 Sqoop

//TODO

5.3 數據清除

#truncate只能刪除管理表中數據,不能刪除外部表中數據
hive (default)> truncate table student;

6 Data Retrieval: Query

查詢語法:

[WITH CommonTableExpression (, CommonTableExpression)*]    (從Hive 0.13.0開始可用)
SELECT 
	[ALL | DISTINCT] select_expr, select_expr, ...
[FROM table_reference]			#從Hive 0.13.0開始可選,如:SELECT 1+1;
[WHERE where_condition]
[GROUP BY col_list]
[HAVING having_condition]
[ORDER BY col_list]
[CLUSTER BY col_list
    | [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT [offset,] rows]			#offset從Hive 2.0.0開始支持
  • SELECT語句可以是聯合查詢或另一個查詢的子查詢的一部分
  • table_reference可以是常規表,視圖,聯接構造或子查詢
  • 表名和列名不區分大小寫
    - 在Hive 0.12和更早版本中,表和列名稱中僅允許使用字母數字和下劃線字符。在Hive 0.13和更高版本中,列名稱可以包含任何 Unicode 字符。反引號(`)中指定的任何列名均按字面意義處理。在反引號字符串中,使用雙反引號(``)表示反引號字符。
    - 要恢復到0.13.0之前的行爲並將列名限制爲字母數字和下劃線字符,請將配置屬性設置 hive.support.quoted.identifiers 爲 none,帶反引號的名稱被解釋爲正則表達式。

6.1 普通查詢

6.1.1 基本查詢

支持的算術運算符有:
+(加) -(減) *(乘) /(除) %(取餘) &(按位取與) |(按位取或) ^ (按位異或)~(按位取反)

#查詢所有列
hive (default)> select * from dept;
#查詢當前數據庫(從Hive 0.13.0開始)
hive (default)> SELECT current_database();
#指定數據庫查詢(從Hive 0.7開始的)
hive (default)> select * from db_hive.emp;
#查詢具體的列,可取別名,as可省略
hive (default)> select deptno as no,dname from dept_normal
#運算符
hive (default)> select sal+1 from emp;

#統計數量
hive (default)> select count(*) cnt from emp;
#取最大值
hive (default)> select max(sal) max_sal from emp;
#取最小值
hive (default)> select min(sal) min_sal from emp;
#取和
hive (default)> select sum(sal) sum_sal from emp;
#取平均值
hive (default)> select avg(sal) avg_sal from emp;

#偏移量默認爲0,查詢5行
hive (default)> select * from emp limit 5;
#偏移量爲2,查詢2行,從Hive 2.0.0開始支持偏移量
hive (default)> select * from emp limit 2,2;

6.1.2 WHERE條件查詢

#where條件查詢,用法與mysql相同
hive (default)> select * from emp where sal >1000;

比較運算符:

操作符 支持的數據類型 描述
A=B 基本數據類型 如果A等於B則返回TRUE,反之返回FALSE
A<=>B 基本數據類型 如果A和B都爲NULL,則返回TRUE,其他的和等號(=)操作符的結果一致,如果任一爲NULL則結果爲NULL
A<>B,A!=B 基本數據類型 A或者B爲NULL則返回NULL;如果A不等於B,則返回TRUE,反之返回FALSE
A<B 基本數據類型 A或者B爲NULL,則返回NULL;如果A小於B,則返回TRUE,反之返回FALSE
A<=B 基本數據類型 A或者B爲NULL,則返回NULL;如果A小於等於B,則返回TRUE,反之返回FALSE
A>B 基本數據類型 A或者B爲NULL,則返回NULL;如果A大於B,則返回TRUE,反之返回FALSE
A>=B 基本數據類型 A或者B爲NULL,則返回NULL;如果A大於等於B,則返回TRUE,反之返回FALSE
A [NOT] BETWEEN B AND C 基本數據類型 如果A,B或者C任一爲NULL,則結果爲NULL。如果A的值大於等於B而且小於或等於C,則結果爲TRUE,反之爲FALSE。如果使用NOT關鍵字則可達到相反的效果。
A IS NULL 所有數據類型 如果A等於NULL,則返回TRUE,反之返回FALSE
A IS NOT NULL 所有數據類型 如果A不等於NULL,則返回TRUE,反之返回FALSE
IN(val1,val2,…) 所有數據類型 使用 IN運算顯示列表中的值
A [NOT] LIKE B STRING 類型 B是一個SQL下的簡單正則表達式,如果A與其匹配的話,則返回TRUE;反之返回FALSE。B的表達式說明如下:‘x%’表示A必須以字母‘x’開頭,‘%x’表示A必須以字母’x’結尾,而‘%x%’表示A包含有字母’x’,可以位於開頭,結尾或者字符串中間。如果使用NOT關鍵字則可達到相反的效果。
A RLIKE B,A REGEXP B STRING 類型 B是一個正則表達式,如果A與其匹配,則返回TRUE;反之返回FALSE。匹配使用的是JDK中的正則表達式接口實現的,因爲正則也依據其中的規則。例如,正則表達式必須和整個字符串A相匹配,而不是隻需與其字符串匹配。

邏輯運算符:

操作符 含義
AND 邏輯並
OR 邏輯或
NOT 邏輯否

6.1.3 Group By分組 與 Having分組篩選

運行mr

#分組查詢+having篩選,用法與mysql相同
hive (default)> select deptno, avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;

6.1.4 Order By/Sort By排序

Order By:全局排序,一個Reducer。

#與mysql中用法相同
hive (default)> select ename, sal*2 twosal from emp order by twosal,ename;

Sort By:每個Reducer內部進行排序,對全局結果集來說不是排序。

#與order by用法相似
hive (default)> select * from emp sort by empno desc;

Distribute By:分區排序,類似MR中partition,進行分區,可以結合sort by一起使用。

#先對deptno進行分區,再按照empno排序
hive (default)> select * from emp distribute by deptno sort by empno desc;

Cluster By:當distribute by和sorts by字段相同時,可以使用cluster by方式。但是排序只能是升序排序,不能指定排序規則爲ASC或者DESC。

hive (default)> select * from emp cluster by deptno;
#等價於
hive (default)> select * from emp distribute by deptno sort by deptno;

6.1.5 分桶及抽樣查詢

分區與分桶:

  • 分區針對的是數據的存儲路徑;分桶針對的是數據文件。
  • 分區提供了一種隔離數據和優化查詢的便利方式。不過,並非所有的數據集都可形成合理的分區,特別是要確定合適的劃分大小。
  • 分桶是將數據集分解成更容易管理的若干部分的另一種技術。

6.1.5.1 分桶表

#根據id創建4個分桶
hive (default)> create table stu_buck(
              > id int,
              > name string
              > )
              > clustered by(id)
              > into 4 buckets
              > row format delimited fields terminated by '\t';
#屬性必須設置爲true              
hive (default)> set hive.enforce.bucketing=true;
#添加的數據無法分桶
hive (default)> load data local inpath '/opt/module/datas/students.txt' into table stu_buck;
#運行的是MR,可以分桶
hive (default)> insert into table stu_buck select id,name from stu;

6.1.5.2 抽樣查詢

語法:TABLESAMPLE(BUCKET x OUT OF y [ON col_name])

hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id);
  • x表示從哪個bucket開始抽取,如果需要取多個bucket,以後的bucket爲當前bucket加上y
  • y必須是table總bucket數的倍數或者因子
  • x的值必須小於等於y的值

6.2 連接查詢

連接查詢中的笛卡兒積會在以下幾種情況下產生:

  • 省略連接條件
  • 連接條件無效
  • 所有表中的所有行互相連接

連接查詢中join…on不支持or

6.2.1 等值連接

Hive支持通常的SQL JOIN語句,但是隻支持等值連接,不支持非等值連接。

hive (default)> select e.empno, e.ename, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno;

6.2.2 內連接

內連接是相對於外連接的,只有滿足關聯條件才輸出,而關聯條件未必是等值關聯,從集合論角度看:等值連接是內連接的子集。

hive (default)> select e.empno, e.ename, d.deptno from emp e join dept d on e.deptno = d.deptno;

6.2.3 左外連接

JOIN操作符左邊表中符合WHERE子句的所有記錄將會被返回。

hive (default)> select e.empno, e.ename, d.deptno from emp e left join dept d on e.deptno = d.deptno;

6.2.4 右外連接

JOIN操作符右邊表中符合WHERE子句的所有記錄將會被返回

hive (default)> select e.empno, e.ename, d.deptno from emp e right join dept d on e.deptno = d.deptno;

6.2.5 滿外連接

將會返回所有表中符合WHERE語句條件的所有記錄。如果任一表的指定字段沒有符合條件的值的話,那麼就使用NULL值替代。

hive (default)> select e.empno, e.ename, d.deptno from emp e full join dept d on e.deptno = d.deptno;

7 函數

7.1 系統內置函數

#查看系統自帶的函數
hive (default)> show functions;
#顯示自帶的函數的用法
hive (default)> desc function upper;
#詳細顯示自帶的函數的用法
hive (default)> desc function extended upper;

常用函數:

  • current_database():查詢當前數據庫。
  • nvl(expr1,expr2):判斷expr1是否爲null,如果爲null用expr2替代,與mysql中ifnull用法相同。
  • case when:與mysql中用法相同。
  • concat(str1,str2,…):拼接字符串。
  • concat_ws(separator,str1,str2,…):它是一個特殊形式的 CONCAT()。第一個參數剩餘參數間的分隔符。分隔符可以是與剩餘參數一樣的字符串。如果分隔符是 NULL,返回值也將爲 NULL。這個函數會跳過分隔符參數後的任何 NULL 和空字符串。分隔符將被加到被連接的字符串之間。
  • collect_set(col):僅支持基本數據類型,將某字段的值進行去重彙總,產生array類型字段。

7.2 自定義函數

用戶自定義函數有三種:

(1)UDF(User-Defined-Function):一進一出
(2)UDAF(User-Defined Aggregation Function):聚集函數,多進一出,類似於:count/max/min
(3)UDTF(User-Defined Table-Generating Functions):一進多出,如lateral view explore()

自定義函數步驟:

  1. 創建一個Maven工程
  2. 導入依賴
    	<dependencies>
    			<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
    			<dependency>
    				<groupId>org.apache.hive</groupId>
    				<artifactId>hive-exec</artifactId>
    				<version>1.2.1</version>
    			</dependency>
    	</dependencies>
    
  3. 創建類繼承org.apache.hadoop.hive.ql.exec.UDF,實現evaluate函數
    package com.yutao.hive;
    public class MyLower extends UDF {
    	
    	public String evaluate (final String s) {
    		if (s == null) {
    			return null;
    		}	
    		return s.toLowerCase();
    	}
    }
    
  4. 打成jar包上傳到服務器/opt/module/jars/udf.jar
  5. 將jar包添加到hive的classpath
    hive (default)> add jar /opt/module/datas/udf.jar;
    
  6. 創建臨時函數與開發好的java class關聯
    hive (default)> create temporary function mylower as "com.yutao.hive.MyLower";
    
  7. 即可在hql中使用自定義的函數strip
    hive (default)> select ename, MyLower(ename) lowername from emp;
    

未完待續。。。

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