(1)hive是一个处理结构化数据的数仓工具;
(2)用户可以在客户端上写HQL语句(是一种类SQL语句),hive将HQL语句转为MR程序,将maptask和reducetask提交到yarn上,分布式运行;
(3)hive是一个工具,只需要在一台机器上安装,指定元数据位置等信息即可。
(1)解析SQL语句;
(2)优化SQL语句;
(3)将SQL语句转化成MR逻辑;
(4)读取数据;
(5)找到元数据的位置;
(6)加载元数据信息。
注:
①元数据记录信息:记录字段、数据类型、分隔符、HDFS的位置;
②元数据位置:(默认在derby数据库中)元数据可以记录在mysql数据库中,处理时先去mysql中读取元数据,然后进行上述处理数据流程。
(1)优点:
①hive的操作接口采用类SQL语法,方便快速开发;
②避免了MR程序,而且内部做了优化,减少学习成本;
③hive适合处理大量数据,对处理小量数据没有优势(小量数据在MySql中进行),hive在处理小量数据时延迟比较高;
④hive中支持用户自定义函数,可以根据自己的需求实现自定义函数;
⑤hive的稳定性较好。
(2)缺点:
①hive的延迟比较高,常用于数据分析对于时效性要求不高的场合(比如处理历史数据);
②hive的HQL表达能力有限:对于递归的迭代式算法无法表达(基于SQL本身的缺点);不擅长进行数据挖掘工作;
③hive的效率比较低,使用Hadoop生态的组件进行存储、调度和执行程序计算;
④hive调优比较困难,力度比较粗。
(1)远程连接:
①hiveserver2 & :后台启动hive远程连接;
②beeline;
③!connect jdbc:hive2://linux01:10000;
④输入用户名:root;
⑤输入密码:空。
**(2)本地启动:**hive。
(3)hive -e “SQL语句”;
执行引号中的语句,其中引号中的SQL语句可以是多句,用“;”隔开。
(4)hive -f sql.sql;
执行文件内容;其中,sql.sql是用SQL语法写的文件。
(5)get
(6)>hive:dfs -get
(7)insert overwrite [local] derectory “路径” select * from tb_name ;
注:overwrite指全量导入,表中前面的数据被覆盖。
(语句写在在hive会话中)
①set mapreduce.framework.name=local; ②set hive.exec.mode.local.auto=true;(1)建表语法:
create table if not exists tb_name(id int,ctime string,event string,sessionid string) row format delimited fields terminated by ",";(2)导入数据:
load data inpath "文件路径" into table tb_name;(3)内部表(MANAGED_TABLE):
内部表指未被external修饰的表;内部表与数据强关联,当导入数据后,数据会从原位置被加载到hive下对应表的文件夹中,被hive管理,文件名与表名对应;当内部表被删除,数据所在的文件夹也会被删除。
(4)适用场景:
内部表适用于业务维度表或者统计好的报表等。
(1)建表语法:
create external table if not exists tb_name(id int,ctime string,event string,sessionid string) row format delimited fields terminated by "," location "文件路径";(2)外部表(EXTERNAL_TABLE):
外部表指被external修饰的表;指定数据的位置,不用导入数据;当外部表被删除,数据不会被删除。
(3)适用场景:
使用公共数据源的一般使用外部表,如:原始数据、日志数据、主题表、事件表、流量表等。
(1)区别:
①内部表数据由Hive自身管理,外部表数据由HDFS管理;
②内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/opt/apps/hive/warehouse);
③外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里); ④删除内部表会直接删除元数据(metadata)及存储数据;
⑤ 删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
⑥对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;);
⑦外部表用来解决共享数据使用问题的;如果有共享数据,多张表要使用相同的数据,选择外部表。
(2)联系:
①内部表转外部表:alter table tb_name set tblproperties("EXTERNAL=TRUE"); ②外部表转内部表:alter table tb_name set tblproperties("EXTERNAL=FALSE"); ③查看表类型:desc formatted tb_name;(Table Type: MANAGED_TABLE -- 内部表;Table Type: EXTERNAL_TABLE -- 外部表)(1)local 本地数据
create table tb_name (id string,age int) row format delimited fields terminated by ","; load data local inpath "本地文件存储路径" into table tb_name;(2)local HDFS数据
hdfs dfs -mkdir -p HDFS中文件路径 hdfs dfs -put 本地文件存储路径 HDFS中文件路径 create table tb_name (id string,age int) row format delimited fields terminated by ","; load data inpath "HDFS中文件存储路径" into table tb_name;(3)建表时指定location
create table tb_name (id string,age int) row format delimited fields terminated by "," location "文件位置";(4)insert into … values…
insert into tb_name values (zss,12); 插入一条数据。(5)insert into … select … from …
①insert into tb_name select 字段名1,字段名2 from tb_name; ②在进行insert之前要先创建一个表,用于存放查询到的数据; ③hive中可以进行并发读写,区别于clickhouse(clickhouse中不能并发写); ④hive中的目录是分文件管理的,数据在不同文件中;而clickhouse的数据在同一文件中。(6)直接将数据put到表目录下
put ... into table tb_name;(7)create table … as select …from…
create table tb_name as select avg(age) as avg_age from tb_user group by gender; 直接创建新表的同时将查询到的数据放入新表中。
(8)import导入(不常用)
①在import导入之前要先导出
导出:export table tb_name to '路径1'; 导入:import table tb_name from '路径1';(9)sqoop、DataX等数据迁移工具
sqoop官方已经停止维护,公司中已经不怎么用了;现在DataX迁移工具用的比较多,可以将HDFS中结构化的数据迁移到mysql中,或者将mysql中数据迁移到HDFS中。
(1)export导出: export table tb_name to ‘路径1’;
(2)dfs -get:>hive:dfs -get “路径”;
(3)hive -e(将数据导出到文件中):hive -e “use database1; select * from tb_name” >> tb_name.txt;
(4)hdfs dfs - get
(5)insert overwrite:insert overwrite local directory “本地路径” row format delimited fields terminated by “\t” select * from tb_name;
(6)数据迁移工具(sqoop、DataX等):sqoop官方已经停止维护,公司中已经不怎么用了;现在DataX迁移工具用的比较多,可以将HDFS中结构化的数据迁移到mysql中,或者将mysql中数据迁移到HDFS中。
TEXTFILE,SEQUENCEFILE,ORC,PARQUET。(其中,前两种是行式存储,后两种是列式存储,一般使用ORC格式)
(1)前提:
①hive目录结构:hive中的数据一般存储在对应的表的目录下,查询数据时先加载目录下所有文件然后在进行筛选过滤;
②快速查找:每天都会有新增的日志数据,不同的数据存储在不同文件中,查询时会加载所有数据进行匹配,效率低下,浪费资源;
③引入分区表,以文件夹为单位,将静态的日志数据分文件夹管理,(也就是文件夹作为分区查询纬度)查询时加载分区内的数据,按照日期定位目录、定位文件位置来进行数据的查询。
(2)数据分区的概念以及存在很久了,通常使用分区来水平分散压力,将数据从物理上移到和使用最频繁的用户更近的地方,以及实现其目的。
hive中处理的数据在HDFS中 , select * from tb_name where dt=2020-06-18 ;查询表中的数据是加载HDFS中对应表文件夹下的数据 ,文件夹下的数据很多,将数据全部加载以后再筛选过滤出数据, 显然效率低 ,Hive中的分区表起始就是根据某中维度将数据分文件夹管理 ,当按照这种维度查询的时候,直接从对应的文件夹下加载数,效率更高!
hive中有分区表的概念,分区表是检索时对数据的优化,还可以将数据以一种符合逻辑的方式进行组织,比如分层存储。
分区表不适合进行多纬度查询。
(多维度查询一般指按照地域、标签等查询生成用户画像;用户画像简单来说就是基于行为特征、信息特征或历史数据等进行标签化,有利于广告精准投放、提升用户黏度、增加收益等)
(3)分类:静态分区表(一般有一次静态分区和二次静态分区);动态分区表。
(1)一次静态分区:
①创建表:
create table tb_name (oid int,dt string,cost double) partitioned by (mt string) row format delimited fields terminated by ","; ②导入数据:
load data local inpath "路径" into table tb_name partition(mt="2020-06"); load data local inpath "路径" into table tb_name partition(mt="2020-07"); ③查询数据:
select * from tb_name where mt='2020-06'; ④注:导入数据时,需要将每个文件都进行导入,每次导入一个;文件导入到相应的分区中;
分区表查询时根据分区字段进行查询。
(2)二次静态分区:
原理与一次静态分区相同,分区中增加了一个纬度。
要根据查询的数据的某个属性进行分区
(1)流程:①建立普通表;②导入数据到普通表;③开启动态分区;④建立分区表;⑤动态导入数据。
(1)逐行运算:类似于for循环。
(2)列式运算:
聚合函数,以组为单位,进行分组查询;可以在组中再次分组。
例子:
select deptno,job.sum(sal) from tb_emp group by deptno,job; 即:按照deptno分组完之后,再按照job分组。
(1)等值匹配:
case a when a1 then 'a1-1' when a2 then 'a2-1' when a3 then 'a3-1' 注:等值匹配存在局限性,只能是一个字段,一般不使用。
(2)条件匹配:
case when a==a1 then 'a1-1' when b==b1 then 'b1-1' when c>c1 then 'c1-1'