1. Hive 简介

1.1. 什么是 HiveHive

是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类 SQL 查询功能。 

本质是将 SQL 转换为 MapReduce 程序。 可以将hive理解为hadoop的一个客户端,因为是hive去连接hdfs,是hive去提交MapReduce程序到hadoop中的ResourceManager主节点。

主要用途:用来做离线数据分析,比直接用 MapReduce 开发效率更高。

1.2. 为什么使用 Hive直接使用 Hadoop MapReduce 处理数据所面临的问题: 

    人员学习成本太高 

    MapReduce 实现复杂查询逻辑开发难度太大 

  使用 Hive : 

    操作接口采用类 SQL 语法,提供快速开发的能力 

    避免了去写 MapReduce,减少开发人员的学习成本 

    功能扩展很方便

2. Hive 架构

2.1. Hive 架构图


hive中月初公式 hive 月初_数据

 

2.2. Hive 组件

用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为 shell 命令行;JDBC/ODBC 是 Hive 的 JAVA 实现,与传统数据库JDBC 类似;WebGUI 是通过浏览器访问 Hive。 

元数据存储:通常是存储在关系数据库如 mysql/derby 中。Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。 

解释器、编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随MapReduce 调用执行。

 

2.3. Hive 与 Hadoop 的关系

Hive 利用 HDFS 存储数据,利用 MapReduce 查询分析数据。 

3. Hive 与传统数据库对比

hive 用于海量数据的离线数据分析。
hive 具有 sql 数据库的外表,但应用场景完全不同,hive 只适合用来做批
量数据统计分析。
更直观的对比请看下面这幅图:

4. Hive 数据模型

Hive 中所有的数据都存储在 HDFS 中,没有专门的数据存储格式 

在创建表时指定数据中的分隔符,Hive 就可以映射成功,解析数据。
Hive 中包含以下数据模型:
db:在 hdfs 中表现为 hive.metastore.warehouse.dir 目录下一个文件夹
table:在 hdfs 中表现所属 db 目录下一个文件夹
external table:数据存放位置可以在 HDFS 任意指定路径
partition:在 hdfs 中表现为 table 目录下的子目录
bucket:在 hdfs 中表现为同一个表目录下根据 hash 散列之后的多个文件

 5. Hive 安装部署 

安装环境 :首先 安装hive要有jdk(1.7以上 我所安装的为1.8版本64位)

      其次要有hadoop集群,hive需要MapReduce和HDFS(hadoop部署可见其他文档)

      mysql :虽然hive内嵌了一个关系型数据库derby。但是内置的derby容量小,有些权限受限,不便于管理。所以使用mysql,用来做表的映射等.(mysql安装可见其他文档)

上传文件Apache Hive jar包 并解压(可以去官网下载hive安装包Index of /apache/hive)

首先要保证mysql可以正常使用 提供mysql下载方法

在线安装

mysql yum install mysql mysql-server mysql-devel

配置 

1 vi conf/hive-env.sh

 hadoop环境变量 在配置文件中找到hadoop_home,linux中安装hadoop的位置

hadoop_home export HADOOP_HOME=/export/server/hadoop-2.7.4(hadoop所在位置)

配置元数据库信息 

1  vi hive-site.xml

添加如下内容:

1 <configuration>
 2 <property>
 3 <name>javax.jdo.option.ConnectionURL</name>
 4 <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
 5 <description>JDBC connect string for a JDBC metastore</description>
 6 </property>
 7 
 8 <property>
 9 <name>javax.jdo.option.ConnectionDriverName</name>
10 <value>com.mysql.jdbc.Driver</value>
11 <description>Driver class name for a JDBC metastore</description>
12 </property>
13 
14 <property>
15 <name>javax.jdo.option.ConnectionUserName</name>
16 <value>root</value>
17 <description>username to use against metastore database</description>
18 </property>
19 
20 <property>
21 <name>javax.jdo.option.ConnectionPassword</name>
22 <value>root</value>
23 <description>password to use against metastore database</description>
24 </property>
25 </configuration>

 

安装完成之后 在hive文件夹下启动 bin/hive

hive中月初公式 hive 月初_Hive_02

 

Hive几种使用方式:
1.Hive交互shell bin/hive

2.Hive JDBC服务(参考java jdbc连接mysql)

3.hive启动为一个服务器,来对外提供服务

bin/hiveserver2


 nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &

启动成功后,可以在别的节点上用beeline去连接

bin/beeline -u jdbc:hive2://mini1:10000 -n root

或者 先启动主节点

bin/hiveserver2 //在主节点作为服务器启动
bin/beeline   //在其他节点上连接


! connect jdbc:hive2://node-1:10000   //node-1为主机名 默认端口号10000

node-1作为主节点启动 node-3做远程连接 连接成功服务器会打印ok

hive中月初公式 hive 月初_Hive_03

hive中月初公式 hive 月初_Hive_04

可以看到 hive源数据库一样 不管是本机启动 还是远程访问 使用的都是mysql中的数据

 

hive中月初公式 hive 月初_hive_05

 六  hive基本操作

DDL 创建表 分隔符 映射数据文件

建表语法

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 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION) 。

Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。

3、 LIKE 允许用户复制现有的表结构,但是不复制数据。

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;

4、 

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,...)]

 

hive 建表的时候默认的分割符是'\001',若在建表的时候没有指明分隔符,load 文件的时候文件的分隔符需要是'\001';若文件分隔符不是'001',程序不会报错,但表查询的结果会全部为'null';

用 vi 编辑器 Ctrl+v 然后 Ctrl+a 即可输入'\001' ----------->   ^A

SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。

Hive 读取文件机制:首先调用 InputFormat(默认 TextInputFormat),返回一条一条记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的 Deserializer,将一条记录切分为各个字段(默认'\001') 。

Hive 写文件机制:将 Row 写入文件时,主要调用 OutputFormat、SerDe 的Seriliazer,顺序与读取相反。

可通过 desc formatted 表名;进行相关信息查看。

当我们的数据格式比较特殊的时候,可以自定义 SerDe。

5、 PARTITIONED BY

在 hive Select 查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了 partition 分区

概念。

分区表指的是在创建表时指定的 partition 的分区空间。一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。表和列名不区分大小写。分区是以字段的形式在表结构中存在,通过 describe table 命令可以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。

6、 STORED AS SEQUENCEFILE|TEXTFILE|RCFILE

如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。

TEXTFILE 是默认的文件格式,使用 DELIMITED 子句来读取分隔的文件。

6、CLUSTERED BY INTO num_buckets BUCKETS

对于每一个表(table)或者分,Hive 可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive 也是针对某一列进行桶的组织。Hive 采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。 

把表(或者分区)组织成桶(Bucket)有两个理由:

(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如 JOIN 操作。对于 JOIN 操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行 JOIN 操作就可以,可以大大较少 JOIN 的数据量。

(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶

段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。


 

SQL语言共分为四大类:

  数据查询语言DQL

  数据操纵语言DML

  数据定义语言DDL

  数据控制语言DCL

与传统sql保持一致

[可加可不加]

| 只选其一

支持传统sql数据类型 与java数据类型

建表的时候要根据表的数据特征 指定分隔符

复杂类型的数据表指定分隔符

默认分隔符

Ctrl v Ctrl a

指定分隔符(逗号分隔符):

create table db1 (id int,name string, age int) row format delimited fields terminated by ',';

复杂类型的数据表指定分隔符:

create table complex_array(name string,work_locations array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',';

下面为具体操作:

表的mysql中 表的映射

结构化的文件 映射为一张表

例如 1,ali

2,anqila

首先上传到hdfs上 hive用hdfs做数据存储

copy文件:

hadoop fs -cp /hivedata/db1.txt /user/hive/warehouse/db.db/db1

分区表

分区表字段 不能在表中已经存在

分区字段的数据来自于装在分区表数据的时候指定的

分区表的字符 在hdfs上的效果就是 建立表的文件夹下面 又创建了子文件夹

这样把数据划分更细致 提高效率

 

单分区建表语句:

create table db3 (id int, name string) partitioned by (country string) row format delimited fields terminated by ',';

单分区导入数据语句:

create table db3 (id int, name string) partitioned by (country string) row format delimited fields terminated by ',';

  

hive中月初公式 hive 月初_hive中月初公式_06


 

分桶表:

创建之前 首先开启分桶功能

#指定开启分桶

set hive.enforce.bucketing = true;

set mapreduce.job.reduces=4;

TRUNCATE TABLE stu_buck;

删除表:

drop table stu_buck;

创建表:

create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdept string)

clustered by(Sno)

sorted by(Sno DESC)

into 4 buckets

row format delimited

fields terminated by ',';

  

创建一个临时表: 将临时表中的数据导入到分桶表中

分桶表导入数据

insert overwrite table stu_buck

select * from student cluster by(Sno);

 

hive中月初公式 hive 月初_hive_07

分桶表的数据 采用 insert+select 插入的数据来自于查询结果(查询的时候执行了mr程序)

对应mr当中的partitioner

hive中月初公式 hive 月初_Hive_08

分桶表(分簇表)创建的时候 分桶表字段 必须是表中已经存在的字段

也就是说 要按照表中的某个字段进行分桶

建立外部表:

create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';

(location'/****'要有相对应的格式化文件)



 

  修改表

 

增加分区:

ALTER TABLE table_name ADD PARTITION (dt='20170101') location '/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一个分区

 

ALTER TABLE table_name ADD PARTITION (dt='2008-08-08', country='us') location


 '/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location  '/path/to/us/part080809';  //一次添加多个分区

 

删除分区:

 

ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08');


ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');

 

  修改分区 

ALTER TABLE table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');

 

添加列 

ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name STRING);  注: ADD 是代表新增一 个 字段, 新增 字段位置在所有列后面 (partition列前 )

  REPLACE则是表示 替换表中所有字段 。

 

 

修改列 

test_change (a int, b int, c int);

 

ALTER TABLE test_change CHANGE a a1 INT; //修改 a 字段名// will change column a's name to a1, a's data type to string, and put it after column b. The new table's structure is: b int, a1 string, c int 
 
 
ALTER TABLE test_change CHANGE a a1 STRING AFTER b; 

// will change column b's name to b1, and put it as the first column. The new table's structure is: b1 int, a ints, c int ALTER TABLE test_change CHANGE b b1 INT FIRST;

 

表重命名 

ALTER TABLE table_name RENAME TO new_table_name

 

 

show tables; //显示当前数据库所有表 
show databases |schemas; //显示所有数据库 
show partitions table_name; //显示表分区信息,不是分区表执行报错 
show functions; //显示当前版本 hive 支持的所有方法 
desc extended table_name; //查看表信息 
desc formatted table_name; //查看表信息(格式化美观) 
describe database database_name; //查看数据库相关信息