1. Hive 概述

Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。

1.1 Hive 架构

大数据010——Hive-LMLPHP

Hive 的结构可以分为以下几部分:

  • 用户接口:包括 CLI, Client, WUI;
  • 元数据存储。通常是存储在关系数据库如 mysql, derby 中;
  • 解释器、编译器、优化器、执行器;
  • Hadoop:用 HDFS 进行存储,利用 MapReduce 进行计算。
  1. 用户接口主要有三个:CLI,Client 和 WebGUI。其中最常用的是 CLI,Cli 启动的时候,会同时启动一个 Hive 副本。Client 是 Hive 的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 HiveServer。 WUI 是通过浏览器访问 Hive。
  2. Hive 将元数据存储在数据库中,如 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
  3. 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。
  4. Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,比如 select * from tbl 不会生成 MapRedcue 任务)。

1.2 Hive 和 Hadoop 关系

大数据010——Hive-LMLPHP

Hive 构建在 Hadoop 之上,

  • HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的;
  • 所有的数据都是存储在 Hadoop 中;
  • 查询计划被转化为 MapReduce 任务,在 Hadoop 中执行(有些查询没有 MR 任务,如:select * from table);
  • Hadoop 和 Hive 都是用 UTF-8 编码的。

1.3 Hive 和普通关系数据库的异同

  1. 查询语言。专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL;
  2. 数据存储位置。Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的;
  3. 数据格式。用户定义数据格式需要指定三个属性:列分隔符(通常为空格、”\t”、”\x001″)、行分隔符(”\n”)以及读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile),加载时无需从用户数据格式到Hive 定义的数据格式的转换,只是将数据复制到相应的HDFS目录下;
  4. 数据更新。Hive 是针对数据仓库应用设计的,所以不支持对数据的改写和添加;
  5. 索引。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势;
  6. 执行。Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的(类似select * from tbl 的查询或查询单个字段不需要 MapReduce);
  7. 执行延迟。由于没有索引,需要扫描整个表,因此延迟较高,另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架;
  8. 可扩展性。由于 Hive 是建立在 Hadoop 之上的,因此 Hive 的可扩展性是和 Hadoop的可扩展性是一致的;
  9. 数据规模;
  10. 数据处理。数据仓库是用来做查询分析的OLAP数据库。

1.4 Hive 元数据库

Hive 将元数据存储在 RDBMS 中,一般常用的有 MYSQL 和 DERBY(内嵌式)。

2. Hive 的部署

2.1 Hive的安装与配置

  1. 安装Hive

    • 首先,Hive是依赖于hadoop系统的,因此在运行Hive之前需要保证已经搭建好hadoop集群环境。

    • 在一个节点上安装关系型数据mysql:

    rpm -qa | grep mysql 	#查看是否安装过mysql
    yum –y remove ***mysql***	#若安装过,卸载
    yum -y install mysql-server mysql-devel	#安装
    service mysqld start	#启动mysql
    mysqladmin -u root password 123456	#创建root管理员
    mysql -u root -p 123456	#登录mysql
    update mysql.user set Host='%' where user="root";	#开放其它主机连接权限
    flush privileges; 		#更新权限
    service mysqld restart		#重启mysql
    
    tar -zvxf apache-hive-1.2.1-bin.tar.gz
    
  2. 配置Hive配置环境变量

    vim ~/.bash_profile
    export HIVE_HOME=/usr/apache-hive-1.2.2-bin
    PATH=$PATH:$HIVE_HOME/bin
    
  3. 替换和添加相关jar包

    –修改HADOOP_HOME/share/hadoop/yarn/lib目录下的jline-*.jar 将其替换成HIVE_HOME/lib下的jline-2.12.jar:

    rm HADOOP_HOME/share/hadoop/yarn/lib/jline.*.jar
    cp HIVE_HOME/lib/jline.*.jar HADOOP_HOME/share/hadoop/yarn/lib/
    

    –将hive连接mysql的jar包(mysql-connector-java-5.1.32-bin.jar)拷贝到hive解压目录的lib目录下:

  4. 修改配置文件

    见下一小节三种安装模式,任选一种。

  5. 启动hive

2.2 Hive的三种安装模式

2.2.1 内嵌Derby单用户模式

这种安装模式的元数据是内嵌在Derby数据库中的,只能允许一个会话连接,数据会存放到HDFS上。这种方式是最简单的存储方式,只需要配置HIVE_HOME/conf/hive-site.xml:

vim HIVE_HOME/conf/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:derby:;databaseName=metastore_db;create=true</value> </property>
    <property>
    	<name>javax.jdo.option.ConnectionDriverName</name>
    	<value>org.apache.derby.jdbc.EmbeddedDriver</value>
    </property>
    <property>
   		<name>hive.metastore.local</name>
    	<value>true</value>
    </property>
    <property>
        <name>hive.metastore.warehouse.dir</name>
        <value>/user/hive/warehouse</value>
    </property>
</configuration>

2.2.2 本地用户模式(重要,多用于本地开发测试)

这种安装方式和嵌入式的区别在于,不再使用内嵌的Derby作为元数据的存储介质,而是使用其他数据库比如MySQL来存储元数据且是一个多用户的模式,运行多个用户client连接到一个数据库中。这种方式一般作为公司内部同时使用Hive。配置HIVE_HOME/conf/hive-site.xml:

vim HIVE_HOME/conf/hive-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
		<name>hive.metastore.warehouse.dir</name>
		<value>/user/hive_rlocal/warehouse</value>
	</property>
	<property>
		<name>hive.metastore.local</name>
		<value>true</value>
	</property>
	<property>
		<name>javax.jdo.option.ConnectionURL</name>
		<value>jdbc:mysql://node01/hive01?createDatabaseIfNotExist=true</value>
	</property>
	<property>
		<name>javax.jdo.option.ConnectionDriverName</name>
		<value>com.mysql.jdbc.Driver</value>
	</property>
	<property>
		<name>javax.jdo.option.ConnectionUserName</name>
		<value>root</value>
	</property>
	<property>
		<name>javax.jdo.option.ConnectionPassword</name>
		<value>123456</value>
	</property>
</configuration>

在node01(安装Hive和mysql的节点)启动hive:

[root@node01 ~]# hive
19/01/14 18:45:09 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist

Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
hive>

2.2.3 远程模式(重要)

  1. Remote 一体

    这种存储方式需要在远端服务器运行一个mysql 服务器,并且需要在 Hive 服务器启动 meta服务。在异于node01(安装mysql)的节点node02中配置HIVE_HOME/conf/hive-site.xml:

    vim HIVE_HOME/conf/hive-site.xml
    
    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    <configuration>
    	<property>
    		<name>hive.metastore.warehouse.dir</name>
    		<value>/user/hive_romote01/warehouse</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionURL</name>
    	   <value>jdbc:mysql://node01:3306/hive02?createDatabaseIfNotExist=true</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionDriverName</name>
    		<value>com.mysql.jdbc.Driver</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionUserName</name>
    		<value>root</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionPassword</name>
    		<value>123456</value>
    	</property>
    	<property>
    		<name>hive.metastore.local</name>
    		<value>false</value>
    	</property>
    </configuration>
    

    在node02(安装Hive的节点)启动hive:

    [root@node02 ~]# hive
    19/01/14 18:45:09 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist
    
    Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
    hive>
    
  2. Remote 分开(公司企业经常用)

    将 hive-site.xml 配置文件拆为如下两部分在两个节点配置:

    1)服务端配置文件,在异于node01(安装mysql)的节点node02中配置HIVE_HOME/conf/hive-site.xml:

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    <configuration>
    	<property>
    		<name>hive.metastore.warehouse.dir</name>
    		<value>/user/hive_romote01/warehouse</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionURL</name>
    	   <value>jdbc:mysql://node02:3306/hive03?createDatabaseIfNotExist=true</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionDriverName</name>
    		<value>com.mysql.jdbc.Driver</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionUserName</name>
    		<value>root</value>
    	</property>
    	<property>
    		<name>javax.jdo.option.ConnectionPassword</name>
    		<value>123456</value>
    	</property>
    </configuration>
    

    2)客户端配置文件,在异于node01(安装mysql)和node02(安装hive服务的)的节点node03中配置HIVE_HOME/conf/hive-site.xml:

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    	<configuration>
    		<property>
    			<name>hive.metastore.warehouse.dir</name>
    			<value>/user/hive/warehouse</value>
    		</property>
    		<property>
    			<name>hive.metastore.local</name>
    			<value>false</value>
    		</property>
    		<property>
    			<name>hive.metastore.uris</name>
    			<!--hive服务端-->
    			<value>thrift://node02:9083</value>
    		</property>
    </configuration>
    

    在node02(安装Hive服务端的节点)启动hive:

    [root@node02 ~]# hive --service metastore
    Starting Hive Metastore Server
    
    

    在node03(安装Hive客户端的节点)启动hive:

    [root@node03 ~]# hive
    19/01/14 19:01:18 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist
    
    Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
    hive>
    

3. HQL 详解

3.1 DDL语句

具体参见:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL;

Hive的数据定义语言 (LanguageManual DDL)重点是 hive 的建表语句和分区。

3.1.1 创建/删除/修改/使用数据库

  1. 查看数据库列表:
hive> show databases;
OK
default #默认数据仓库
Time taken: 1.04 seconds, Fetched: 2 row(s)
hive>
  1. 创建数据库:
语法:CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment];
  1. 删除数据库
语法:DROP (DATABASE|SCHEMA) [IF EXISTS] database_name;
  1. 修改数据库(了解)
语法:ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES  (property_name=property_value, ...);
	 ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role;
  1. 使用数据库
USE database_name;
Use default;

3.1.2 创建/删除/表(*)

  1. 创建表(重要!)
数据类型:
data_type
  : primitive_type  原始数据类型
  | array_type		数组
  | map_type		map
  | struct_type
  | union_type  -- (Note: Available in Hive 0.7.0 and later)

primitive_type
  : TINYINT
  | SMALLINT
  | INT
  | BIGINT
  | BOOLEAN
  | FLOAT
  | DOUBLE
  | DOUBLE PRECISION
  | STRING  基本可以搞定一切
  | BINARY
  | TIMESTAMP
  | DECIMAL
  | DECIMAL(precision, scale)
  | DATE
  | VARCHAR
  | CHAR
array_type
  : ARRAY < data_type >
map_type
  : MAP < primitive_type, data_type >
struct_type
  : STRUCT < col_name : data_type [COMMENT col_comment], ...>
union_type
   : UNIONTYPE < data_type, data_type, ... >

建表实例:

create table abc(
 id int,
 name string,
 age int,
 likes array<string>,
 address map<string,string>
 )
 row format delimited fields terminated by ',' 	# 字段之间的分隔符
 COLLECTION ITEMS TERMINATED by '-'				# 一个字段各个item的分隔符
 map keys terminated by ':'						# map键值之间的分隔符
 lines terminated by '\n';						# 行分隔符

外部关键字EXTERNAL允许您创建一个表,并提供一个位置,以便hive不使用这个表的默认位置。这方便如果你已经生成的数据。当删除一个外部表,表中的数据不是从文件系统中删除。外部表指向任何HDFS的存储位置,而不是存储在配置属性指定的文件夹hive.metastore.warehouse.dir中。

  1. 删除表
语法:DROP TABLE [IF EXISTS] table_name [PURGE];

3.1.3 修改表,更新,删除数据(这些很少用)

重命名表:

语法:ALTER TABLE table_name RENAME TO new_table_name;

更新数据:

语法:UPDATE tablename SET column = value [, column = value ...] [WHERE expression]

删除数据:

语法:DELETE FROM tablename [WHERE expression]

3.2 DML语句

具体参见:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML;

Hive数据操作语言([LanguageManual DML](javascript:changelink(‘https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML’,'EN2ZH_CN’)😉),重点是数据加载和查询插入语法。

3.2.1 四种插入/导入数据(重要)

Hive不能很好的支持用insert语句一条一条的进行插入操作,不支持update操作。数据是以load的方式加载到建立好的表中。数据一旦导入就不可以修改。

  • 第一种:

从HDFS上导数据

语法:LOAD DATA INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

从本地服务器上导数据

语法:LOAD DATA LOCAL INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
  • 第二种

创建person2表,然后从表person1…中导入数据:

语法:INSERT OVERWRITE TABLE person2 [PARTITION (partcol1=val1, partcol2=val2 ...)]
	 SELECT id,name,age From person1;
  • 第三种
语法:FROM person1 t1
	 INSERT OVERWRITE TABLE person2 [PARTITION (partcol1=val1, partcol2=val2 ...)]
       SELECT t1.id, t1.name, t1.age

from放前面好处就是后面可以插入多条语句,如:

FROM person1 t1
INSERT OVERWRITE TABLE person2
 SELECT t1.id,t1.name,t1.age,t1.likes,t1.address where…
INSERT OVERWRITE TABLE person3
 SELECT t1.id,t1.name,t1.age,t1.likes,t1.address where…;
  • 第四种( 不建议)
INSERT INTO TABLE person1
	VALUES(1,'zhangsa',18),(2,'zhangsa',22)

3.2.2 查询数据并保存

  • 保存数据到本地:
insert overwrite local directory '/opt/datas/person1'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select * from person ;

查看数据:

hive> !cat /opt/datas/person1/000000_0;
1,zhangsan,18,gamegirlbook,stu_addrbeijingwork_addrshanghai
2,lishi,16,shopboybook,stu_addrhunanwork_addrshanghai
3,wang2mazi,20,fangniueat,stu_addrshanghaiwork_addrtianjing
hive>
  • 保存数据到HDFS上:
nsert overwrite directory '/user/hive_remote02/hive/person'
select * from person ;
  • 在shell中将数据重定向到文件中:
[root@node03 ~]# hive -e "select * from mydb.person;" > /opt/datas/person2.txt
19/01/14 19:57:35 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist

Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
OK
Time taken: 4.235 seconds, Fetched: 3 row(s)
[root@node03 ~]#

3.2.3 备份数据或还原数据

  1. 备份数据:
EXPORT TABLE person TO '/user/hadoop/hive/datas/export/person_bak' ;
  1. 删除再还原数据:
先删除表
drop table person;
show tables from mydb;
再还原数据:
IMPORT TABLE person_new FROM '/user/hadoop/hive/datas/export/person_bak' ;

3.2.4 Hive的其它函数

Hive的group by\join(left join right join等)\having\sort by \order by等操作和MySQL没有什么大的区别。

3.3 Hive SerDe

Hive SerDe - Serializer and Deserializer SerDe 用于做序列化和反序列化。构建在数据存储和执行引擎之间,对两者实现解耦。

Hive通过ROW
FORMAT DELIMITED以及SERDE进行内容的读写:

row_format(语法)
: DELIMITED
          [FIELDS TERMINATED BY char [ESCAPED 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, ...)]

如 /root/hivedata.txt 存在如下数据:

192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217

Hive正则匹配创建表:

 CREATE TABLE logtbl (
    host STRING,
    identity STRING,
    t_user STRING,
    time STRING,
    request STRING,
    referer STRING,
    agent STRING)
  ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
  WITH SERDEPROPERTIES (
    "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
  )
  STORED AS TEXTFILE;

反序列化加载数据:

hive> load data local inpath '/root/hivedata.txt' overwrite into table logtbl;
Loading data to table mydb.logtbl
Table mydb.logtbl stats: [numFiles=1, numRows=0, totalSize=551, rawDataSize=0]
OK
Time taken: 5.362 seconds
hive> select * from logtbl;
OK
192.168.57.4	-	-	29/Feb/2016:18:14:35 +0800	GET /bg-upper.png HTTP/1.1	304	-
192.168.57.4	-	-	29/Feb/2016:18:14:35 +0800	GET /bg-nav.png HTTP/1.1	304	-
192.168.57.4	-	-	29/Feb/2016:18:14:35 +0800	GET /asf-logo.png HTTP/1.1	304	-
192.168.57.4	-	-	29/Feb/2016:18:14:35 +0800	GET /bg-button.png HTTP/1.1	304	-
192.168.57.4	-	-	29/Feb/2016:18:14:35 +0800	GET /bg-middle.png HTTP/1.1	304	-
192.168.57.4	-	-	29/Feb/2016:18:14:36 +0800	GET / HTTP/1.1	200	11217
192.168.57.4	-	-	29/Feb/2016:18:14:36 +0800	GET / HTTP/1.1	200	11217
Time taken: 0.189 seconds, Fetched: 7 row(s)
hive>

4. Beeline 和 Hiveserver2

hiveserver2直接启动(hive服务器所在节点):

[root@node02 ~]# hiveserver2
OK
OK

启动 beeline(hive客户端所在节点):

[root@node03 ~]# beeline
Beeline version 1.2.1 by Apache Hive
beeline> !connect jdbc:hive2://node02:10000 root 123456
Connecting to jdbc:hive2://node02:10000
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node02:10000> show databases;
+----------------+--+
| database_name  |
+----------------+--+
| default        |
| mydb           |
+----------------+--+
2 rows selected (1.426 seconds)
1: jdbc:hive2://node02:10000>

5. Hive分区

5.1 Hive的分区partition(重要)

假如现在我们公司一天产生3亿的数据量,那么为了方便管理和查询,此时可以建立分区(可按日期 部门等具体业务分区),区分类别的管理。需要注意:

  • 必须在表定义时创建partition;
  • 分区分为:单分区和多分区;
  • 分区分为:静态分区和动态分区。

5.1.1 创建分区

  1. 单分区建表语句:
create
table day_table(id int, content string) partitioned by (dt string) row format
delimited fields terminated by ',';

单分区表,按天分区,在表结构中存在id,content,dt三列,以dt为文件夹区分;

  1. 双分区建表语句:
create table day_hour_table (id int, content string) partitioned by (dt string, hour string) row format delimited fields terminated by ',';

双分区表,按天和小时分区,在表结构中新增加了dt和hour两列;先以dt为文件夹,再以hour子文件夹区分。

注意:在创建 删除多分区等操作时一定要注意分区的先后顺序,他们是父子节点的关系。分区字段不要和表字段相同。

5.1.2 添加分区表的分区

表已创建,在此基础上添加分区:

ALTER TABLE table_name
ADD partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...

5.1.3 删除分区

语法:ALTER TABLE table_name DROP partition_spec, partition_spec,...

注意:用户可以用ALTER TABLE DROP PARTITION 来删除分区,分区的元数据和数据将被一并删除。

5.1.4 数据加载进分区表中

语法:LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1,partcol2=val2 ...)]

例如:

 LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08-08', hour='08');

5.1.5 查看分区语句

hive> show partitions table_name;

5.1.6 重命名分区

语法:ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION 			          partition_spec;

5.1.7 动态分区(重要)

  1. 在本地文件/root/hivedata.txt中写入以下4行数据:

    aaa,US,CA
    aaa,US,CB
    bbb,CA,BB
    bbb,CA,BC
    
  2. 建立非分区表并加载数据

    hive> CREATE TABLE t1 (name STRING, cty STRING, st STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
    hive> LOAD DATA LOCAL INPATH '/root/hivedata.txt' INTO TABLE t1;
    SELECT * FROM t1;
    
  3. 建立外部分区表并动态加载数据 (注意删除外部表的相关事项)

    hive> CREATE EXTERNAL TABLE t2 (name STRING) PARTITIONED BY (country STRING, state STRING);
    
  4. 动态分区的参数

    set hive.exec.dynamic.partition;#是否开启动态分区功能,默认false关闭
    set hive.exec.dynamic.partition.mode;#动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。
    set hive.exec.max.dynamic.partitions.pernode;#默认值:100,在每个执行MR的节点上,最大可以创建多少个动态分区。
    set hive.exec.max.dynamic.partitions;#默认值:1000,在所有执行MR的节点上,最大一共可以创建多少个动态分区。
    set hive.exec.max.created.files;#默认值:100000整个MR Job中,最大可以创建多少个HDFS文件。
    set hive.error.on.empty.partition;#默认值:false当有空分区生成时,是否抛出异常。一般不需要设置。
    
  5. 设置动态分区参数

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    set hive.exec.max.dynamic.partitions.pernode=1000;
    
  6. 加载数据

    INSERT INTO TABLE t2 PARTITION (country, state) SELECT name, cty, st FROM t1;
    

6. 函数自定义

自定义函数包括三种 UDF、UDAF、UDTF:

  • UDF:一进一出
  • UDAF:聚集函数,多进一出。如:Count/max/min
  • UDTF:一进多出,如 lateralview explore()

使用方式 :在HIVE会话中add自定义函数的jar 文件,然后创建 function 继而使用函数,后续总结。

7. 分桶

7.1 分桶表及应用场景

分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储(类似MapReduce中的默认partition对于Key值得分区)。对于hive中每一个表、分区都可以进一步进行分桶。由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。

适用场景:数据抽样( sampling )、map-join。

7.2 开启支持分桶

hive> set hive.enforce.bucketing=true;

注意:一次作业产生的桶(文件数量)和reduce task个数一致。

7.3 往分桶表中加载数据

语法:insert into table bucket_table select columns from tbl;

7.4 抽样查询

语法:select * from bucket_table tablesample(bucket 1 out of 4 on columns);
TABLESAMPLE语法:
TABLESAMPLE(BUCKET x OUT OF y)
x:表示从哪个bucket开始抽取数据
y:必须为该表总bucket数的倍数或因子
01-31 12:48