1hive的特点
hive是一个基于hadoop的数据仓库,将结构化的数据映射为数据库表,并提供HQL查询功能,底层数据仍然存储在HDFS上,Hive的本质是将SQL语句转换为MapReduce任务进行。不熟悉mapreduce的用户也可以很方便地使用HQL处理和计算hdfs上结构化的数据,适用于离线的批量数据计算。
1.1 数据仓库 与 数据库
- (1) 概念
数据库存储,精细化地管理数据。分库分表存储数据。
数据仓库中,数据没有细化区分。只管理数据,可能什么数据都有。类似打包,eg:桌面很乱,将所有文件打包到一个文件中。 - (2) 用途
数据库:增删改
数据仓库:查询 - (3) 使用
数据库:标准sql
分布式数据库hbase:非标准sql,例如NoSQL。
数据仓库:方言版的sql - (4) 模式
数据库:写模式,在加载数据的时候检查数据是否与表模式匹配。
分布式数据库hbase:非严格模式
数据仓库:读模式,加载数据时不检查数据,查询时检查。
1.2 将结构化的数据映射为数据库表
mysql:将数据映射为二维表
结构化数据:每一行上,列比较规整的数据。(将文本中的一行数据映射为表中的一条数据,将文本中的一列数据映射为表中的一个字段)
1.3 底层数据存储在HDFS上
Hive管理的数据仍旧存在HDFS上,Hive中的表仅仅是HDFS里结构化数据的映射。
Hive的作用:管理数据,不存储数据。
Hive管理HDFS上的表,就要建立一个关联关系,将Hive中的表和HDFS的数据路径关联起来。用一个元数据库记录该关联数据,这种元数据库通常采用MySQL,Hive默认的是derby。
元数据:hive中的表和hdfs中数据的映射关系、hive中表属性(内部表、外部表、视图)、字段信息(字段类型、字段顺序等)。元数据即描述数据的数据。
元数据非常重要,元数据一旦丢失,hive中的库和表都会丢失。
1.4 Hive的本质是将SQL语句转换为MapReduce执行
Hive中存储着很多map、reduce模板,当用户在执行一条SQL语句的时候,会将SQL语句转换为MapReduce任务执行。SQL语句中有select、from等关键字,hive解析这些关键字,最终翻译成map reduce 执行。
所以说,hive就是一个hadoop上的工具而已,它使用的数据存储在hdfs上,计算使用mr。
2 hive的优点? or 为什么使用hive?
- 可扩展
hive能够自由扩展集群规模,不需要重启服务。
横向扩展:加服务器。
纵向扩展:添加硬件资源。例如:CPU4核8线程到8核16线程,只需要将内存从64g扩展到128G 。 - 延展性
自定义函数,用户可以实现自己的需求。 - 容错性强
即使有几个结点故障,SQL也能正常查询数据。
缺点:
- 不支持删除、更新。
- 延迟性高。
- 不支持事务。因为hive中做的最多的是查询操作。
3 hive和传统数据库RDBMS对比
-
数据量,事务
hive存储的数据量比较大,适合海量数据,适合存储轨迹类历史数据,适合用来做离线分析、数据挖掘运算,事务性较差,实时性较差;
rdbms一般数据量相对来说不会太大,适合事务性计算,实时性较好,更加接近上层业务 -
计算引擎
hive的计算引擎是hadoop的mapreduce,存储是hadoop的hdfs文件系统;
rdbms的引擎由数据库自己设计实现例如mysql的innoDB,存储用的是数据库服务器本地的文件系统 -
扩展性
hive由于基于hadoop所以存储和计算的扩展能力都很好;
rdbms在这方面比较弱,比如orcale的分表和扩容就很头疼。 -
索引
hive表格没有主键、没有索引、不支持对具体某一行的操作,适合对批量数据的操作,不支持对数据的update操作,更新的话一般是先删除表然后重新落数据;
rdbms事务性强,有主键、索引,支持对具体某一行的增删改查等操作。 -
查询语言
hive的SQL为HQL,与标准的RDBMS的SQL存在有不少的区别,相对来说功能有限;
rdbms的SQL为标准SQL,功能较为强大。 -
数据加载模式
Hive在加载数据时候和rdbms关系数据库不同,hive在加载数据时候不会对数据进行检查,也不会更改被加载的数据文件,而检查数据格式的操作是在查询操作时候执行,这种模式叫“读时模式”。
在实际应用中,写时模式在加载数据时候会对列进行索引,对数据进行压缩,因此加载数据的速度很慢,但是当数据加载好了,我们去查询数据的时候,速度很快。
但是当我们的数据是非结构化,存储模式也是未知时候,关系数据操作这种场景就麻烦多了,这时候hive就会发挥它的优势。
.
rdbms里,表的加载模式是在数据加载时候强制确定的(表的加载模式是指数据库存储数据的文件格式),如果加载数据时候发现加载的数据不符合模式,关系数据库则会拒绝加载数据,这个就叫“写时模式”,写时模式会在数据加载时候对数据模式进行检查校验的操作。
.
最后做下总结,HIVE是数据仓库适合存储历史的海量的数据,适合做批量和海量复杂运算,事务性差,运算时间长。
RDBMS是数据库,存储数据量偏小一些,事务性强,适合做OLTP和OLAP业务,运算时间短。
4 hive架构
1)用户接口层
Cli 即命令行客户端,是最常用的方式。
JDBC、ODBC,通过Java API操作hive。
Web ui:太丑,基本不用。
2) 元数据库
存储元数据,元数据库一般选用MySQL。
3)Thrift服务
提供跨语言的服务,所以能用java操作hive数据库。
4)Driver 驱动层
驱动器:将sql解析为mr,并提交到hadoop。
编译器:将sql语句转化成mr。(将sql通过map、reduce模板,编译成mr程序,生成一个逻辑执行计划。)
优化器:优化mr。(很多 sql编译成的mr,存在重复的操作,优化器将重复的操作过滤掉。
)
5 hive 内部表 和 外部表 的区别
创建方式:
内部表:create table…
外部表:create external table …
- 内部表
create table…
创建内部表时,加载数据,实际数据会被移动到数据仓库的数据目录中。
删除内部表时,表中的元数据和数据仓库中对应的数据会一同被删除。 - 外部表
create external table …
创建外部表时,需指向数据存储器中已经存在的数据,表的创建和数据的加载两个步骤同时完成。
删除外部表时,只有元数据会被删除,数据存储器中的实际数据不会被删除。
6 hive分区表 和 分桶表的区别
- 分区:将数据按照业务存在不同的目录下。一个分区,对应表所在目录下的相应子目录。
例如:
/hive/warehouse/driver/city=‘北京’/log_beijing.txt
/hive/warehouse/driver/city=‘上海’/log_beijing.txt
/hive/warehouse/driver/city=‘广州’/log_beijing.txt
select* from driver where city=‘北京’ ;这条语句就不用全表扫描了。
一般使用日期作为分区字段。
分区表作用: 提高查询性能。 - 分桶:每个分区基于表的某列数据的哈希值,被划分为若干个桶,每个桶对应分区下的一个数据文件。
例如
/hive/warehouse/driver/city=‘北京’/part-r-00000
/hive/warehouse/driver/city=‘北京’/part-r-00001
/hive/warehouse/driver/city=‘北京’/part-r-00002
/hive/warehouse/driver/city=‘北京’/part-r-00003
分桶表作用:
1)分桶表提高join性能。
2)提升抽取样本的质量。
7 分区表和分桶表的数据加载
7.1 分区表
create table if not exists ptn_table(id int,age int) partitioned by (city string);
向分区表加载数据,须先添加分区,再向分区中加载数据。
7.1.1 添加分区
- 静态分区:向分区表添加之前手动添加一个指定分区
一次插入一个分区:
alter table ptn_table add partition(city=‘北京’);
一次插入多个分区:
alter table ptn_table add partition(city=‘济南’,city=‘青岛’,city=‘长沙’);
分区个数不确定,例如年龄,添加分区的时候怎么添加?上面的方式不使用
- 动态分区:根据数据自动分区,不需要提前添加分区
开启动态分区模式:
set hive.exec.dynamic.partition = true; #是否开启动态分区,默认就是开启的(true)
hive.exec.dynamic.partition.mode = nonstrict; #默认是strict(严格模式,必须手动添加静态分区)
7.1.2 动态生成分区,并加载数据:
- 一个分区字段
insert into table stu_ptn partition(age) select id,name,sex,department,age from student;
如果使用动态分区,查询插入时,动态分区字段必须放在最后一个字段。 - 多个分区字段
insert into table stu_ptn partition(department,age) select id,name,sex,department,age from student;
分区字段也是放在select后字段的末尾。
hive1.2中,如果是多个分区,需要指定第一个分区的值。
insert into table stu_ptn partition(department=‘IS’,age) select id,name,sex,department,age from student;
分区表在使用的时候,分区字段就可以看作一个普通字段。
select * from stu_ptn where age = 18;
只是在建表和添加数据的时候不一样。
7.2 分桶表
create table if not exists stu_buk(id int,name string,sex string,age int,department string) clustered by (age) sortedd by(sex) into 4 buckets row format delimited fields terminated by ‘,’;
- 分桶表数据加载:
insert into stu_buk select * from stu;#默认按照分桶,将数据分到不同的桶中。按桶的个数确定reducetask的个数。
但是分桶表不允许使用load方式
7 视图
hive中的视图仅是逻辑视图,不存储数据,仅相当于SQL语句的快捷方式或别名。
视图的操作有:
创建视图:create view as select_statement;
删除视图:drop view viewname;
修改视图:alter view viewname set tblproperties table_properties;
重定义视图的select:alter view view_name as select_statement
8 连接
-
内连接:两表中都有的才会连接上
-
外连接
左外连接:左表为基表
右外连接:
全外连接:两个合并 两表中所有的id列出
表a | 表b |
---|---|
1 | 1 |
2 | 2 |
3 | 5 |
全外连接:
1
2
3
5
- 半连接:
semi join
只取一半 即其中一表的一半
左半连接:
在右表中存在的左表中的数据
右半连接:
在左表中存在的右表中的数据
9 cluster by/distribute by/sort by/order by
-
cluster by = distribute by + sort by
cluster by 和 sort by 不可以同时使用
当分组字段和排序字段是同一个字段时,才能使用cluster by代替 -
distribute by col_list:类似于分桶,在单个reduce task中,只分组不排序。
按照指定的distribute by 字段和设置的reduce tasks 进行分组,但是不进行排序。 -
sort by :局部排序 在单个reduce task 中进行排序。只有一个reducetask时,效果和order by相同。
-
order by :全局排序
建表语句和查询语句中容易混淆:
- 建表语句
clustered by 、sorted by、 partitioned by - 查询语句
order by 、sort by、 distribute by 、cluster by
clustered by 与 cluster by两者没有关联。其他的类似。
10 hive的排名
row_number | rank | dense_rank |
---|---|---|
排名加行号 | 跳跃排名 | 连续排名 |
用法相同:
row_number() over(分组规则 排序规则)
rank() over(分组规则 培训规则)
dense_rank() over(分组规则 排序规则)
业务需求中会出现分组topN的需求。
row_number: 分组,排名,编行号。即无并列排名。
分组加排名 在每一组内排序 加行号 从1开始 顺序添加
eg:select id,name,sex,age,department,row_number() over(partition by department order by age) as rank from student;
rank:跳跃排名,也叫计数排名。即有并列跳跃排名。
用于排名,有并列第1,即多个第1。并列后跳跃
select id,name,sex,age,department,rank() over(order by age desc) from student;
1
1
3
4
5
dense_rank:即有并列连续排名。
用于排名,有并列名次。并列后名次连续。
1
1
2
3
3
10 hive的启动方式
hive有两种启动方式
(1)hive命令
这种方式只能在安装hive的结点使用,在其他结点不能访问。
(2)hiveserver2 + beeline
先在主节点执行hiveserver2命令,相当于建立了一个服务端。
然后在任意结点可通过beeline命令,连接hiveserver2。
需要指定连接jdbc:
!connect jdbc:hive2://hadoop01:10000