1. Hive
1.1 什么是Hive
1.1.1 hive简介
Hive:由Facebook开源用于解决海量结构化日志的数据统计工具。
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类sQL查询功能。
hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能;可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉mapreduce的用户可以很方便地利用SQL语言查询、汇总和分析数据。
1.1.2 Hive本质:将HQL转化为MapReduce程序
(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)数据挖掘方面不擅长,由于 MapReduce 数据处理流程的限制,效率更高的算法却无法实现。
2 )Hive 的效率比较低
(1)Hive 自动生成的 MapReduce 作业,通常情况下不够智能化 (2)Hive 调优比较困难,粒度较粗
1.3 Hive 和数据库比较
由于 Hive 采用了类似 SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,再无类似之处。 本文将从多个方面来阐述 Hive 和数据库的差异。数据库可以用在 Online 的应用中,但是 Hive 是为数据仓库而设计的,清楚这一点,有助于从应用角度理解 Hive 的特性。
1.3.1 查询语言
由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查 询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开发。
1.3.2 数据更新
由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive 中不建议对数据的改写,所有的数据都是在加载的时候确定好的。 而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET 修改数据。
1.3.3 执行延迟
Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导 致 Hive 执行延迟高的因素是 MapReduce 框架。由于 MapReduce 本身具有较高的延迟,因此 在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。 当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候, Hive 的并行计算显然能体现出优势。
2. Hive数据类型
2.1 基本数据类型
数据类型 | 长度 | 例子 |
---|---|---|
TINYINT | 1byte有符号整数 | 20 |
SMALINT | 2byte有符号整数 | 20 |
INT | 4byte有符号整数 | 20 |
BIGINT | 8byte有符号整数 | 20 |
BOOLEAN | 布尔类型,true或者false | TRUE FALSE |
FLOAT | 单精度浮点数 | 3.14159 |
DOUBLE | 双精度浮点数 | 3.14159 |
STRING | 字符系列。可以指定字符集。可以使用单引号或者双引号。 | '我是STRING类型' |
TIMESTAMP | 时间类型 | '2013-01-31 00:13:00.345’ |
BINARY | 字节数组(二进制) | 1010 |
2.2 集合数据类型
数据类型 | 描述 | 语法示例 |
---|---|---|
STRUCT | 相当于java语言当中没有方法的对象,只有属性。例如,如果某个列的数据类型是STRUCT{first STRING, last STRING},那么第1个元素可以通过字段.first 来引用。 | struct() |
MAP | MAP是一组键-值对元组集合,使用数组表示法可以访问数据。例如,如果某个列的数据类型是MAP,其中键->值对是’first’->’John’和’last’->’Doe’,那么可以通过字段名[‘last’] 获取最后一个元素 | map() |
ARRAY | 数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。例如,数组值为[‘John’, ‘Doe’],那么第2个元素可以通过数组名[1] 进行引用。 | Array() |
2.3 类型转换
使用cast
操作显示进行数据类型转换,例如:
cast('1' AS INT) # 将字符串‘1’转换成整数1 # 前提参数1的值必须为纯数字的字符串1 cast('X' AS INT) # 转换失败,返回NULL值
3. DDL数据定义
3.1 创建数据库
create database 数据库名称;
若要避免创建数据库已存在的错误,可以使用IF NOT EXISTS
进行判断。(标准写法)
create database if not exists 数据库名称; # 表示:如果数据库如果不存在则执行前面的CREATE进行创建
也可以指定数据库在HDFS上存放的位置
create database if not exists 数据库名称 location 'hdfs路径';
3.2 查询数据库
显示数据库
show databases;
过滤显示数据库(模糊查询)
show databases like '*关键词*';
查看数据库详情
desc database 数据名称;
切换数据库
use 目标数据库名称;
3.3 删除数据库
删除空数据库
drop database 数据库名称;
为避免报错删除的数据库不存在,可以用if exists
进行判断
drop database if exists 数据库名称;
如果要删除的数据库中已有数据,可以用cascade
命令进行强制删除
drop database if exists 数据库名称 cascade;
3.4 创建表
建表语法
create [external] table [if not exists] 表名 (列名 数据类型 [comment 字段注释],....) [comment 表注释] [partitioned by (列名 数据类型)[comment 字段注释],....] [clustered by (列名,列名...)] [row format delimited fields terminated by '分隔符'] [location 'hdfs路径']
名词解释
-
external
关键字可以创建一个外部表,不写为内部表 -
if not exists
避免报错创建的表已存在 -
comment
注释 -
partitoned by
创建分区表 -
clustered by
创建分桶表 -
row format delimited fields terminated by
指定一个分隔符 -
location
指定表在hdfs上的存储位置
3.5 内部表
默认创建的表都是所谓的管理表,也称为内部表。
当我们删除一个管理表时,Hive也会删除这个表中数据。
普通创建表
create table if not exists student2( id int, name string ) row format delimited fields terminated by '\t';
复制表(表结构+表数据)
create table if not exists 表名 as select语句;
复制表结构
create table if not exists 新表名 like 要复制表结构的表名;
查看表结构(表信息并非数据)
desc formatted 表名;
向表中导入数据
load data local inpath '本地路径' into table 表名;
-
准备数据(stu)
-
加载本地文件(stu)到外部表 stdent2中
load data local inpath '/data/stu' into table student2;
-
检验数据
3.6 外部表
删除表的时候,不会删除表内的数据,只会删除元数据。
创建外部表
create external table if not exists student5( id int, name string ) row format delimited fields terminated by ',';
向表中导入数据
load data local inpath '本地路径' into table 表名;
-
准备数据(student)
-
加载本地文件(student)到外部表 stdent5中
load data local inpath '/data/student' into table student5;
-
验证数据是否导入成功
select * from student5;
3.7 内部表与外部表的转换
内部表转外部表
alter table 内部表名称 set tblproperties('EXTERNAL'='TRUE');
外部表转内部表
alter table 外部表名称 set tblproperties('EXTERNAL'='FALSE')
注意:('EXTERNAL'='TRUE')
和('EXTERNAL'='FALSE')
是固定写法,严格区分大小写
3.8 分区表
简单的说,分区就是给表在加一个伪列
分区表实际上就是对应一个HDFS文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。分区表实际上是一种优化手段,分的是文件夹
准备工作:
将dept.txt表的数据导出放入到 '/opt/module/datas/' 目录下
dept.txt数据准备: 10, ACCOUNTING, NEW YORK 20, RESEARCH, DALLAS 30, SALES, CHICAGO 40, OPERATIONS, BOSTON
1)创建分区表:
create table dept_partition( deptno int, dname string, loc string ) partitioned by (month string) row format delimited fields terminated by ','; -- 指定分隔符
2)将'/opt/module/datas/dapt.txt'中的数据加载到表中:
load data local inpath '/opt/module/datas/dept.txt' into table dept_partition partition(month='201709');
3)查询分区的数据:
select * from dept_partition where month='201709';
4)增加分区:
load data local inpath '/opt/module/datas/dept.txt' into table dept_partition partition(month='201710');
验证:
5)删除分区:
alter table dept_partition drop partition (month='201710');
验证:
6)查看有多少分区:
show partitions dept_partition;
3.9 分桶表
分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分。(分区后,分区内的表,可以再进行分桶)分桶是将数据集分解成更容易管理的若干部分的另一个技术。
分桶表,也是将数据集拆分开。这个分开不是针对于文件夹,而是针对于文件。将一张表文件,做了分桶,会将数据拆分成多个小文件。分桶表在数据集极大时会才会使用。分桶表可以配合后续的抽样查询。分桶表做了解即可。
1)数据准备:
将student_info.txt表的数据导出放入到 '/opt/module/datas/' 目录下
文档 内容如下: 1,Lucy 2,Lily 3,James 4,Bob 5,John 6,Mary 7,Paul 8,Slide 9,Clark 10,Smith 11,Smart 12,Lilei 13,Andra 14,Donic 15,Jelly 16,Chris 17,Schla 18,Elea 19,Flink 20,Grash
2)分桶表创建语句:
create table stu_buck(id int, name string) clustered by(id) -- 分桶表分桶字段,必须是已有字段,不能指定类型(分区表则必须是创建表时不存在的字段) into 4 buckets -- 表示分几个桶 row format delimited fields terminated by ','; -- 指定分隔符
3)导入数据:
load data local inpath '/opt/module/datas/student_info.txt' into table stu_buck;
验证数据是否导入成功:
查看是否分为四个桶
4)查看每个桶的数据:
查看第2个桶:
hadoop fs -cat /user/hive/warehouse/stu_buck/000000_0
查看第2个桶:
hadoop fs -cat /user/hive/warehouse/stu_buck/000001_0
查看第3个桶:
hadoop fs -cat /user/hive/warehouse/stu_buck/000002_0
查看第4个桶:
hadoop fs -cat /user/hive/warehouse/stu_buck/000003_0
3.10 分区表和分桶表的区别
分区针对的是数据的存储路径;分桶针对的是数据文件。
4. 修改表
4.1 重命名表
alter table 表名 rename to 新表名;
4.2 增加列
alter table 表名 add columns(列名 数据类型);
当表中已存放数据时,往后增加的列,对应的属性值都为NULL值。
4.3 更新列
alter table 表名 change column 列名 desc 类型; # 如下图:将student_new 表中的 age 列修改为 string 类型
4.4 替换列
alter table 表名 replace columns(列名 类型,列名 类型, 列名 类型,...); # 某种意义上可以用来修改列名 当表中已有数据时,替换列时不能修改数据类型,在该情况下也就是说只能修改列名了;
4.5 删除表
drop table 表名;
注意:如果想要把外部表删除干净的话,需要先转为内部表在执行drop,或者直接执行drop然后再适合用hdfs删除数据。
5. DML操作
5.1 导入数据
load data [local] inpath '路径' [overwrite] into table 表名 [partition (分区列=值)]
名词解释:
-
local:表示从本地加载到hive中,不写的话就是从hdfs上加载。
-
overwrite:表示覆盖之前的数据,不写的话就是追加数据。
-
partition:表示将数据加载到哪个分区
5.2 insert插入
普通插入
insert into 表名 values(值,值,..);
指定列插入
insert into 表名(列,列,..) values(值,值,..);
指定分区插入
insert into 表名 partition(分区列 = 分区值) values(值,值,..);
6. 查询
hive的查询语句跟SQL极其相似,就拿我们的Oracle来说,Oracle中能用语法以及函数都可以在hive中使用,但是hive不支持不等连接;关于SQL查询可以关注我,看我以前发布的文章