Hive的基本介绍
什么是Hive?
Hive是基于Hadoop的一个数据仓库工具,可以将结构化数据映射为一张数据库表,并提供类SQL查询功能,Hive利用HDFS进行存储,利用MapReduce查询分析数据
本质是将SQL转换为MapReduce应用程序,比直接使用MapReduce开发效率高
Hive的源数据存储?
通常是存储在关系型数据库中 mysql/derby中。Hive将元数据村处在数据库中。Hive中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表),表的数据所在目录等
Hive与传统DB的区别?
传统数据库:OLTP -->面向事务(Transaction)操作型处理就是关系型数据库:Mysql,oracle sqlserver db2 主要是支持业务,面向业务
Hive -->面向分析(Analytical)分析型处理 就是数据仓库,面对的是历史数据(历史数据中的一部分就来自于数据库)开展分析
Hive数仓开发的基本流程
1)从业务系统获取数据
- Sqoop导入数据库的数据:sqoop可以在Hive与传统的数据库间进行数据传递,可以将一个关系型数据库中的数据导入到Hadoop的HDFS中,也可以将HDFS的数据导入到关系型数据库中。
- Flume采集文本数据:Flume可以将各类型的文件进行采集,存放到HDFS中。
- FTP文件服务器:从文件服务器上下载分析所需要的源数据(增量数据,全量数据)。如下图
2)数据存储
- 数据仓库分层:ods层,dw层,da层
- 源数据层ODS:直接引用外围的数据,没有统一格式化的,不会直接应用使用,不利于分析
- 数据仓库层DW:来自于ODS要经过ETL的过程,格式统一,数据规整,干净清洁
- 数据应用层DA:要去用DW层数据,真正的数据使用者
- 数据集市:数据集市也叫数据市场,数据集市就是满足特定的部门或者用户的需求,按照多维的方式进行存储,包括定义为度。需要计算指标,维度的层次等,生成面向决策分析需求的数据立方体
3)写SQL开发需求
4)配置调度系统
5)导出数据并展示
Hive sql知识点
1)DML & DDL
DML:数据操作语言,负责对数据库对象运行数据访问工作的指令集:delete from table_name
DDL:数据定义语言:用于定义和管理数据库中的对象:truncate table table_name
2)外表和内表
内部表:
create table student(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ','
未被external修饰,表数据由Hive自身管理,表数据存储的位置是默认的hive.metastore.warehouse.dir,删表会直接删除元数据及存储的数据,对表的修改将会直接同步给元数据的内部表
外部表:
create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';
被external修饰的,表数据由HDFS管理,表数据的存储位置由自己指定,删除表仅仅删除元数据,hdfs上的文件并不会被删除或者修改的是外部表。
3)分区,分桶
分区——为了避免select查询的时候全表扫描问题,hive提出了分区表概念,给文件归类,打上标识(表示不能为表中已有字段)静态分区:
单分区建表 create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';
加载 load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab partition (sex='man');
在新建分区表的时候,系统会在hive数据仓库默认路径/user/hive/warehouse/下创建一个目录(表名),再创建目录的子目录sex=man(分区名),后在分区名下存放实际的数据文件。
多分区建表create table par_tab_muilt (name string, nation string) partitioned by (sex string,dt string) row format delimited fields terminated by ',' ;
加载:load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab_muilt partition (sex='man',dt='2018-05-26');
新建表的时候定义的分区顺序,决定了文件目录顺序(谁是父目录谁是子目录),因为有了这个层级关系,当我们查询所有man的时候,man以下的所有日期下的数据都会被查出来。如果只查询日期分区,但父目录sex=man和sex=woman都有该日期的数据,那么Hive会对输入路径进行修剪,从而只扫描日期分区,性别分区不作过滤(即查询结果包含了所有性别)。
动态分区
静态分区在插入的时候必须首先要知道有什么分区类型,而且每个分区写一个load data,太烦人。使用动态分区可解决以上问题,其可以根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。
开启动态分区功能set hive.exec.dynamic.partition=true;
加载数据 insert overwrite table par_dnm partition(sex='man',dt) select name, nation, dt from par_tab;
注:
1.动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。
2.动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode 。
set hive.exec.dynamic.partition.mode;
hive.exec.dynamic.partition.mode=strict
它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。修改后即可。
set hive.exec.dynamic.partition.mode=nostrick;
总结:
1、分区表是为了减少查询时候的全表扫描而出现。
2、分区表的现象就是在表的文件夹下多了一个文件夹 而文件夹的名字就是分区 字段=分区值
3、分区字段的值在查询的时候 会显示出来 但是并不代表结构化数据中有这个字段 分区字段是一个虚拟字段 只是用来标识文件
方便用户查询的时候 根据这个标识进行过滤 从而减少了全局扫描
4、分区表的数据通过load data的方式加载 加载的时候要指定分区的值(这个分区的值就是这批数据文件夹名字的值)
5、关于分区字段一定不会是表中存在的字段 如果是直接编译报错 体会什么叫给数据打标识
分桶
1.为了提高join查询时的效率 减少了笛卡尔积的数量,分桶表出现。
clustered by (字段) into num_buckets buckets(如:clustered by (sex) into 2 buckets)
2.分桶的功能默认不开启 需要自己手动开启 set hive.enforce.bucketing = true;
3.分成几桶 也需要自己指定 set mapreduce.job.reduces=N;
4.分通表导入数据的方式:insert+select insert数据来自于后select查询的结果
insert overwrite table stu_buck
select * from student cluster by(Sno);