一、hive简介
hive并不是完整的数据库。hive依赖于hdfs,是一款数据分析工具,将提交的sql转化为对应的mapReduce任务,交由hadoop来处理,hive也可以结合spark来用,spark对比hadoop来说更加的高效,更加快速,spark的计算都是在内存中进行的。
hive的限制:
1、hive不支持行级别的更新,插入或者删除(orc格式存储是支持行级别更新的,且支持acid的事务)。
2、每次启动mapReduce任务也需要耗费时间。
3、hive不支持OLTP(联机事务)
二、mapReduce
mapreduce是一种计算模型,可以将一个大的数据处理任务分解成为单个的、可以在服务器集群执行的并行执行的任务。
两个过程:map、reduce
map:将数据进行转换。数据从一种形式转换成另一种形式。
reduce:对数据进行聚合操作的过程。
mapReduce过程会有一个shuffle阶段,就是map输出的数据到reduce输入数据的过程(写内存,排序,写磁盘,跨网络传输)
三、hive基础操作
hive -f *.sql 指定一个文件中的一个或者多个进行查询
hive -e 执行一个sql就退出cli
hive -S -e “set” 查看属性
$HOME/.hiverc文件可以添加频繁设置的命令
$HOME/.hivehistory 操作执行的历史命令
hive cli可以执行简单的bash shell命令:!命令; 需要再开始加上!结尾加上;
hive cli可以使用hadoop的一些命令;
四、基本数据类型和文件格式
1、基本数据类型
tinyint: 1byte的有符号整数
smallint:2byte的有符号整数
int:4byte的有符号整数
bigint: 8byte的有符号整数
boolean: 布尔类型
float: 单精度浮点
double: 双精度浮点
string: 字符串,可以指定字符集,单双引号都可以
timestamp: 整数,浮点,或者字符串(jdbc约定的字符串YYYY-MM-DD hh:mm:ss.fffff)
binary: 字节数组
这些都是对java类接口的实现,和java的类型基本一致。跟传统的关系型数据库不一样,hive讲究优化磁盘的读写性能,而不是限制字段的长度。
2、集合数据类型:
STRUCT:
MAP:
ARRAY:
3、文件数据编码
hive默认的记录和字段分割符
\n:分割每行、
^A (ctrl + A) :分割每列,在linux的bash中看不到、
^B:分割array或者struct中的元素
^C:map的键和值的分割
用户可以自己指定分割符
create table table_name(
file type
)row format delimited
fields terminated by ‘\001’
collection Items terminated by ‘\002’
map keys terminated by ‘\003’
lines terminated by ‘\n’
stored as textfile;
\002 代表B,\001代表A ,\003代表 ^C
4、读时模式
hive不会在数据装载时对数据进行验证,hive会在查询时对数据进行验证。
文件内容和表结构不匹配:
1、记录数少于表的字段数,则缺少的字段都表示为null
2、数值类型的字段对应非数值类型的记录,记录会被显示为null
五、数据定义
1、表管理
hive会为每个数据库创建一个目录,表会以子目录的形式存在,default没有目录,默认在hive.metastore.warehouse.dir下存放表。
hive建表时会自动增加连个属性,last_modified_by、last_modified_time。
管理表(内部表):
删除表的时候会把数据和表一起删除。
缺点:不便于共享数据
外部表:删除表只会删除表的元数据,不会删除表中的数据
创建外部表: external 关键字和location,describe extended table_name;
create external table table_name(
file_name file_type
)
location ‘hdfs_path’
2、表类型
分区表、分桶表。
分区表:分为静态分区表和动态分区表,查看分区:show partitions tableName;
静态分区表
静态分区表的创建:
指定分区字段、添加静态的分区(根据分区字段的值来添加)
可以用hadoop的fs命令直接删除hive表的指定分区,因为hive对于表是否存在该分区并不关心,如果分区目录不存在或者分区文件夹下没有数据,则对该分区过滤时会直接返回空。
动态分区表:
hive底层是使用hdfs作为存储的,hdfs是设计存储百万的大文件的,而不是大量的小文件。过多的分区会创建大量的文件和文件夹。NameNode维护这文件系统所有的元数据信息,并保存在内存中,大量的小文件会增加NameNode的压力。
######开启动态分区
set hive.exec.dynamic.partition=true;
######开启分区模式为非严格模式,严格模式必在动态分区前加上一个静态分区
set hive.exec.dynamic.partition.mode=nonstrict;
#####每个mapper或者reducer可以创建的最大动态分区个数
set hive.exec.max.dynamic.partitions.pernode=100
#####一个动态建表语句可以创建的最大分区个数
set hive.exec.max.dynamic.partitions=+1000
#####全局创建的最大文件个数
set hive.exec.max.created.files=100000
分桶表:
可以避免由于创建过多的分区而导致超过文件系统的处理能力。
可以强制hive为目标表的分桶初始化一个正确的reduce个数
set hive.enforce.bucketing=true;
也可以手动指定
#####设置reduce任务为3
set mapreduce.job.reduce=3;
3、表存储格式
textfile、rcfile(行列文件)、parquet、sequencefile、orcfile(优化的行列文件)
后两者都是通过二进制存储和压缩(可选)来优化磁盘存储和I/O宽带性能的。
4、删除表
drop table table_name;
hadoop回收站功能:fs.trash.interval 1440 (24小时)回收站的检查点的时间间隔
hadoop有回收站功能,删除数据后会被转移到hdfs的根目录的.Trash目录下。如果要重建的话,需要将目录移出到原来的目录下就行了。
5、修改表
alter table table_name rename to new_table_name;
alter table table_name add partition(columnName=‘’);
alter table table_name drop partition(columnName=‘’);
#####修改表字段名、类型、并将字段位置进行更改
alter table table_name change column columnName new_columnName columnType comment after column_nmae;
alter table table_name change column columnName new_columnName columnType comment first;
alter table table_name add columns(
column_name columnType comment ‘’
)
alter table table_name repplace columns( columnName type ,columnName type);
#####修改表属性
alter table tableName set tblproperties( key=value)
#####修改表存储属性
alter table tableName set fileformat sequencefile;
六、数据操作
1、装载数据:
load data local inpath ‘Local file system path’ overwrite into table tableName partition()
local关键字对应的是本地文件系统,会将本地文件系统的数据考本一份。
如果是hdfs,则省略local,那么会将hdfs的文件移动到对应表的目录下,hdfs中数据只会存在一份。
装载的限制:表定义存储格式必须和文件格式一致,hive会对格式进行验证。
2、导出数据
insert overwrite local director ‘path’
select * from employees;
一个或者多个文件会被写入文件夹,具体个数取决于调用的reduce个数。编码方式和hive存储格式一样。
七、数据查询
1、本地模式
本地模式:在单台机器上执行所有的任务,对于小数据集执行时间会明显缩短。
set hive.exec.mode.local.auto=true;
set hive.exec.mode.local.auto.inputbytes.max=50000000;
set hive.exec.mode.local.auto.input.files.max=10;
使用本地模式执行可以添加到$HOME/.hiverc文件中。
简单查询避免mapreduce
select * fromemployees、以及where中只对分区字段的过滤,类似的简单查询是不需要mapreduce过程的,开启本地模式可以加快执行速度。
2、关于浮点数的比较
hive在进行数字比较的时候会进行类型的提升,比如表中字段value是float, 查询的时候有一个条件为value>0.2,这是你会发现等于0.2的记录也被输出了。这是因为所有使用ieee编码的系统都存在这个问题。
三种解决方法 :
1、将value字段类型定义为double
2、显式指定0.2为float cast(0.2 as float)
3、钱相关的避免使用浮点数
3、like和relike
like用于普通的开头,中间,结尾
reike用于正则表达式
4、join相关
join支持等值连接,不支持不等值连接,等于或者多余三张表连接,每个on字句使用相同的连接键只会产生一个mapreduce任务。
连接顺序小表—>大表
5、order by、sort by、distribute by、cluster by:
order by: 会对结果进行全局排序,所有的数据都会通过一个reducer进行处理
sort by: 会在每个reduce中对数据进行排序,会进行局部的排序(但是不保证全局的有序性),可以提高全局排序的效率。但是对于reducer大于1的排序,可能每个局部的数据都会有重叠
distribute by:可以和sort by结合使用,可以将相同的键的数据发送到相同的reducer中,然后再使用sort进行局部排序。
cluster by: 如果distribute by和sort by所使用的键相同,则可以使用cluster by代替
6、开启压缩
查看是否开启压缩
set hive.exec.compress.intermediate;
开启压缩会降低磁盘i/o,从而提高执行速度(对于I/O密集型可以大大提高效率)