Bootstrap

0基础学习Hive

一、初识数据仓库

1. 主要特征 

2. 数据仓库、数据库、数据集市

3. 分层架构

4. 案例:场景分析:美团点评酒旅数仓建设实践

5. ETL 和 ELT

二、Hive

1. 案例:模拟hive

2. hive 架构组件

2.1 和 mysql 对比

2.2 元数据 

三、Hive 的部署

1. 远程模式的安装

1.1 解压安装

  • 上传安装包 解压

    tar zxvf apache-hive-3.1.2-bin.tar.gz
  • 解决Hive与Hadoop之间guava版本差异

    cd /export/server/apache-hive-3.1.2-bin/
    rm -rf lib/guava-19.0.jar
    cp /export/server/hadoop-3.3.0/share/hadoop/common/lib/guava-27.0-jre.jar ./lib/

1.2 修改配置文件 

hive-env.sh

cd /export/server/apache-hive-3.1.2-bin/conf
mv hive-env.sh.template hive-env.sh

vim hive-env.sh
export HADOOP_HOME=/export/server/hadoop-3.3.0
export HIVE_CONF_DIR=/export/server/apache-hive-3.1.2-bin/conf
export HIVE_AUX_JARS_PATH=/export/server/apache-hive-3.1.2-bin/lib

hive-site.xml

vim hive-site.xml

<configuration>
<!-- 存储元数据mysql相关配置 -->
<property>
	<name>javax.jdo.option.ConnectionURL</name>
	<value>jdbc:mysql://node1:3306/hive3?createDatabaseIfNotExist=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8</value>
</property>

<property>
	<name>javax.jdo.option.ConnectionDriverName</name>
	<value>com.mysql.jdbc.Driver</value>
</property>

<property>
	<name>javax.jdo.option.ConnectionUserName</name>
	<value>root</value>
</property>

<property>
	<name>javax.jdo.option.ConnectionPassword</name>
	<value>hadoop</value>
</property>

<!-- H2S运行绑定host -->
<property>
    <name>hive.server2.thrift.bind.host</name>
    <value>node1</value>
</property>

<!-- 远程模式部署metastore metastore地址 -->
<property>
    <name>hive.metastore.uris</name>
    <value>thrift://node1:9083</value>
</property>

<!-- 关闭元数据存储授权  --> 
<property>
    <name>hive.metastore.event.db.notification.api.auth</name>
    <value>false</value>
</property>
</configuration>

上传mysql jdbc驱动到hive安装包lib下

mysql-connector-java-5.1.32.jar

初始化元数据

cd /export/server/apache-hive-3.1.2-bin/
​
bin/schematool -initSchema -dbType mysql -verbos
#初始化成功会在mysql中创建74张表

在hdfs创建hive存储目录(可选)

hadoop fs -mkdir /tmp
hadoop fs -mkdir -p /user/hive/warehouse
hadoop fs -chmod g+w /tmp
hadoop fs -chmod g+w /user/hive/warehouse

1.3 启动hive

1、启动metastore服务

#前台启动  关闭ctrl+c
/export/server/apache-hive-3.1.2-bin/bin/hive --service metastore
​
#前台启动开启debug日志
/export/server/apache-hive-3.1.2-bin/bin/hive --service metastore --hiveconf hive.root.logger=DEBUG,console  
​
#后台启动 进程挂起  关闭使用jps+ kill -9
nohup /export/server/apache-hive-3.1.2-bin/bin/hive --service metastore &

客户端连接

拷贝node1安装包到客户端机器上(node3)

scp -r /export/server/apache-hive-3.1.2-bin/ node3:/export/server/


vi hive/conf/hive-site.xml

<configuration>
<!-- 远程模式部署metastore metastore地址 -->
<property>
    <name>hive.metastore.uris</name>
    <value>thrift://node1:9083</value>
</property>

</configuration>

直接在bin目录启动hive

启动hiveserver2服务

  nohup /export/server/apache-hive-3.1.2-bin/bin/hive --service hiveserver2 &
​
  #注意 启动hiveserver2需要一定的时间  不要启动之后立即beeline连接 可能连接不上
bode3: /export/server/apache-hive-3.1.2-bin/bin/beeline

beeline> ! connect jdbc:hive2://node1:10000
beeline> root
beeline> 直接回车

四、DDL Hive建表预计

1. 建表语法

2. 数据类型 

hive的隐式转换 

3. 错误类型

compiling statement  => 编译错误 语法错误

processing statement  => 执行错误 逻辑问题

4. hive 读写机制

4.1 读 

复杂数据类型建表

数据源

vim set_data.txt

1,孙悟空,53,西部大嫖客:2888-大圣娶亲:888-至尊宝:888
2,韩信,52,飞衡:888-白龙吟:1288
3,鲁班七号,54,木偶奇遇记:288-电玩小子:2888-星空梦想:88888                                                     

建表

create table set_data(
    id int,
    name string,
    win_rate int.
    skin_price map<string,int
)
row format delimited 
fields terminated by ',' #字段分隔符
collection items terminated by '-' #集合之间分割符
map keys terminated by ':'; #集合中元素分割符

4.2 默认分隔符

4.3 存储路径

--在建表的时候 可以使用1ocation关键字指定表的路径在HDFS任意位置
create table tteam_ace_player location(
    id int,
    team_name string,
    ace_player_name string
)
1ocation'/aaa'; --使用1ocation关键字指定本张表数据在hdfs上的存储路径

4.4 内部表和外部表

五、分区、分桶

1. 分区 

1.1 分区表的创建

--经过大脑分析 我们认为应该根据角色主定位进行分区 所以分区的字段就是ro1e_main
create table t_a11 hero_part(
    id int,
    name string,
    hp_max int,mp_max int,
    attack_max int,
    defense_max int,
    attack_range string,
    role_main string
    --role_assist string
)
partitioned by(role_main string)
row format delimited
fields terminated by "\t";

partitioned by( role_main string ) 分区字段

分区字段不能在表中出现

1.2 分区表数据加载

1.2.1 静态分区

1.2.2 动态分区

设置允许动态分区、设置动态分区模式

set hive.exec.dynamic.partition=true;--注意hive3已经默认开启了

--模式分为strict严格模式 
--nonstrict非严格模式严格模式要求 分区字段中至少有一个分区是静态分区。
set hive.exec.dynamic.partition.mode=nonstrict;

动态分区加载数据 

insert + select
插入的数据来自于后面的查询语句返回的结果。
查询返回的内容,其字段类型、顺序、个数要和待插入的表保持一致。

--执行动态分区插入--注意 分区值并没有手动写死指定
insert into table t_a1f_hero_part_dynamic partition(role_dong)
select tmp.*,tmp.role_main from t_a11_hero tmp;--查询返回10个字段

2. 分桶

从语法层面解析分桶含义
CLUSTERED BY XXX INTO N BUCKEIS    
--根据xxx字段把数据分成N桶
--根据表中的字段把数据文件成为N个部分


t_user(id int,name string);

--1、根据谁分?
CLUSTERED BY xXX;    xxx必须是表中的字段
--2、分成几桶?
N BUCKETS;    N的值就是分桶的个数
--3、分桶的规则?
clustered by id into 3 bucket

hashfunc(分桶字段)%Nbucket 余数相同的来到同一个桶中
1、如果分桶的字段是数字类型的字段,hashfunc(分桶字段)=分桶字段本身
2、如果分桶的字段是字符串或者其他字段,hashfunc(分桶字段)=分桶字段.hashcode

3. DDL的其他语法

3.1 数据库DDL

3.2 数据表DDL

六、Hive DML

1. load 加载数据

演示

--step1:建表
--建表student_1oca1 用于演示从本地加载数据
create table student_1ocal
(num int,name string,sex string,age int,dept string) 
rowformat delimited fields terminated by ',';

--建表student_HDFS 用于演示从HDFS加载数据到非分区表
create table student_HDFs(
num int,name string,sex string,age int,dept string
)
rowformat delimited fields terminated by ',';

--建表student_HDFS_p 用于演示从HDFS加载数据到分区表
create table student _HoFs_p(
num int,name string,sex string,age int,dept string
)
partitioned by(country string) row format delimited fields terminated by ',';
--step2:加载数据
--从本地加载数据数据位于HS2(node1)本地文件系统本质是hadoop fs -put上传操作
--Loading data to table itheima.student_1ocal from file:/root/hivedata/students.txt
LOAD DATA LOCAL INPATH '/root/hivedata/students.txt' INTO TABLE student_1ocal;


--从HDFS加载数据 数据位于HDFS文件系统根目录下本质是hadoopfs-mv 移动操作
--Loading data to table itheima.student hdfs from hdfs://nodel:8020/stu/students.txt
--先把数据上传到HDFs上 hadoop fs -put /root/hivedata/students.txt /
LOAD DATA INPATH '/students,txt' INTO TABLE student_HDFS;

----从HDFS加载数据到分区表中并指定分区数据位于HDFS文件系统根目录下
--先把数据上传到HDFs上 hadoop fs -put /root/hivedata/students.txt /
LOAD DATA INPATH '/students.txt' INTO TABLE student_HDFS_p partition(country="China");

2. insert 插入数据

3. insert 数据导出

七、Hive DQL

1. 基础查询

------------案例:美国Covid-19新冠数据之select查询---------------
--step1:创建普通表t_usa_covid19
drop table if exists t_usa_covid19;
CREATE TABLE t_usa_covid19(
       count_date string,
       county string,
       state string,
       fips int,
       cases int,
       deaths int)
row format delimited fields terminated by ",";
--将源数据load加载到t_usa_covid19表对应的路径下
load data local inpath '/hivedata/us-covid19-counties.dat' into table t_usa_covid19;

select * from t_usa_covid19;

--step2:创建一张分区表 基于count_date日期,state州进行分区
CREATE TABLE if not exists t_usa_covid19_p(
     county string,
     fips int,
     cases int,
     deaths int)
partitioned by(count_date string,state string)
row format delimited fields terminated by ",";

--step3:使用动态分区插入将数据导入t_usa_covid19_p中
set hive.exec.dynamic.partition.mode = nonstrict;

insert into table t_usa_covid19_p partition (count_date,state)
select county,fips,cases,deaths,count_date,state from t_usa_covid19;

HAVINGWHERE区别

  • having是在分组后对数据进行过滤
  • where是在分组前对数据进行过滤
  • having后面可以使用聚合函数
  • where后面不可以使用聚合函数

2. 高阶查询

2.1 分桶排序

set mapreduce.job.reduces =3; 设置为分三个桶

若不指定则自动分桶

select * from student cluster by tept; --自动分桶
select * from student distribute by tept sort by age; --分桶且排序

2.3 Union联合查询

select * from student
union
select * from student1
order by num; --先合并再排序

select * from(select * from student order by num)
union
select * from(select * from student1 order by num)
order by num; --先排序再合并

2.4 公用表表达式CTE

with stu as ( select * from student)
from stu
select *; --from风格

--链式
with stu as ( select * from student),
     stu1 as (select * from student1)
select *  from stu
union
select * from stu1;

--view
create view V1 as
with stu as ( select * from student)
select * from stu;

3. JOIN 表连接

八、内置函数

1. Hive CLI

2. 配置属性

3. 内置运算符

--显示所有的函数和运算符
show functions;
--查看运算符或者函数的使用说明
describe function +;
--使用extended 可以查看更加详细的使用说明
describe function extended count;

--1、创建表dual
create table dual(id string);
--2、加载一个文件dual.txt到dual表中
--dual.txt只有一行内容:内容为一个空格
load data local inpath '/root/hivedata/dual.txt' into table dual;
--3、在select查询语句中使用dual表完成运算符、函数功能测试
select 1+1 from dual;

select 1+1;

3.1 关系运算符

----------------Hive中关系运算符--------------------------
--is null空值判断
select 1 from dual where 'itcast' is null;

--is not null 非空值判断
select 1 from dual where 'itcast' is not null;

--like比较: _表示任意单个字符 %表示任意数量字符
--否定比较: NOT A like B
select 1 from dual where 'itcast' like 'it_';
select 1 from dual where 'itcast' like 'it%';
select 1 from dual where  'itcast' not like 'hadoo_';
select 1 from dual where  not 'itcast' like 'hadoo_';

--rlike:确定字符串是否匹配正则表达式,是REGEXP_LIKE()的同义词。
select 1 from dual where 'itcast' rlike '^i.*t$';
select 1 from dual where '123456' rlike '^\\d+$';  --判断是否全为数字
select 1 from dual where '123456aa' rlike '^\\d+$';

--regexp:功能与rlike相同 用于判断字符串是否匹配正则表达式
select 1 from dual where 'itcast' regexp '^i.*t$';

3.2 算数运算符 

-------------------Hive中算术运算符---------------------------------
--取整操作: div  给出将A除以B所得的整数部分。例如17 div 3得出5。
select 17 div 3;

--取余操作: %  也叫做取模mod  A除以B所得的余数部分
select 17 % 3;

--位与操作: &  A和B按位进行与操作的结果。 与表示两个都为1则结果为1
select 4 & 8 from dual;  --4转换二进制:0100 8转换二进制:1000
select 6 & 4 from dual;  --4转换二进制:0100 6转换二进制:0110

--位或操作: |  A和B按位进行或操作的结果  或表示有一个为1则结果为1
select 4 | 8 from dual;
select 6 | 4 from dual;

--位异或操作: ^ A和B按位进行异或操作的结果 异或表示两者的值不同,则结果为1
select 4 ^ 8 from dual;
select 6 ^ 4 from dual;

3.3 逻辑运算符

--3、Hive逻辑运算符
--与操作: A AND B   如果A和B均为TRUE,则为TRUE,否则为FALSE。如果A或B为NULL,则为NULL。
select 1 from dual where 3>1 and 2>1;
--或操作: A OR B   如果A或B或两者均为TRUE,则为TRUE,否则为FALSE。
select 1 from dual where 3>1 or 2!=2;
--非操作: NOT A 、!A   如果A为FALSE,则为TRUE;如果A为NULL,则为NULL。否则为FALSE。
select 1 from dual where not 2>1;
select 1 from dual where !2=1;
--在:A IN (val1, val2, ...)  如果A等于任何值,则为TRUE。
select 1 from dual where 11  in(11,22,33);
--不在:A NOT IN (val1, val2, ...) 如果A不等于任何值,则为TRUE
select 1 from dual where 11 not in(22,33,44);

4. 用户定义函数UDF分类标准

5. 常见内置函数

show function; --有哪儿些函数
describe function extended get_json_object; --函数说明手册

5.1 字符串函数

------------String Functions 字符串函数------------
select concat("angela","baby");
--带分隔符字符串连接函数:concat_ws(separator, [string | array(string)]+)
select concat_ws('.', 'www', array('itcast', 'cn'));
--字符串截取函数:substr(str, pos[, len]) 或者  substring(str, pos[, len])
select substr("angelababy",-2); --pos是从1开始的索引,如果为负数则倒着数
select substr("angelababy",2,2);
--正则表达式替换函数:regexp_replace(str, regexp, rep)
select regexp_replace('100-200', '(\\d+)', 'num');
--正则表达式解析函数:regexp_extract(str, regexp[, idx]) 提取正则匹配到的指定组内容
select regexp_extract('100-200', '(\\d+)-(\\d+)', 2);
--URL解析函数:parse_url 注意要想一次解析出多个 可以使用parse_url_tuple这个UDTF函数
select parse_url('http://www.itcast.cn/path/p1.php?query=1', 'HOST');
--分割字符串函数: split(str, regex)
select split('apache hive', '\\s+');
--json解析函数:get_json_object(json_txt, path)
--$表示json对象
select get_json_object('[{"website":"www.itcast.cn","name":"allenwoon"}, {"website":"cloud.itcast.com","name":"carbondata 中文文档"}]', '$.[1].website');



--字符串长度函数:length(str | binary)
select length("angelababy");
--字符串反转函数:reverse
select reverse("angelababy");
--字符串连接函数:concat(str1, str2, ... strN)
--字符串转大写函数:upper,ucase
select upper("angelababy");
select ucase("angelababy");
--字符串转小写函数:lower,lcase
select lower("ANGELABABY");
select lcase("ANGELABABY");
--去空格函数:trim 去除左右两边的空格
select trim(" angelababy ");
--左边去空格函数:ltrim
select ltrim(" angelababy ");
--右边去空格函数:rtrim
select rtrim(" angelababy ");
--空格字符串函数:space(n) 返回指定个数空格
select space(4);
--重复字符串函数:repeat(str, n) 重复str字符串n次
select repeat("angela",2);
--首字符ascii函数:ascii
select ascii("angela");  --a对应ASCII 97
--左补足函数:lpad
select lpad('hi', 5, '??');  --???hi
select lpad('hi', 1, '??');  --h
--右补足函数:rpad
select rpad('hi', 5, '??');
--集合查找函数: find_in_set(str,str_array)
select find_in_set('a','abc,b,ab,c,def');

5.2 日期函数

----------- Date Functions 日期函数 -----------------
--获取当前日期: current_date
select current_date();
--获取当前时间戳: current_timestamp
--同一查询中对current_timestamp的所有调用均返回相同的值。
select current_timestamp();
--获取当前UNIX时间戳函数: unix_timestamp
select unix_timestamp();
--日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp("2011-12-07 13:01:03");
--指定格式日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp('20111207 13:01:03','yyyyMMdd HH:mm:ss');
--UNIX时间戳转日期函数: from_unixtime
select from_unixtime(1618238391);
select from_unixtime(0, 'yyyy-MM-dd HH:mm:ss');
--日期比较函数: datediff  日期格式要求'yyyy-MM-dd HH:mm:ss' or 'yyyy-MM-dd'
select datediff('2012-12-08','2012-05-09');
--日期增加函数: date_add
select date_add('2012-02-28',10);
--日期减少函数: date_sub
select date_sub('2012-01-1',10);


--抽取日期函数: to_date
select to_date('2009-07-30 04:17:52');
--日期转年函数: year
select year('2009-07-30 04:17:52');
--日期转月函数: month
select month('2009-07-30 04:17:52');
--日期转天函数: day
select day('2009-07-30 04:17:52');
--日期转小时函数: hour
select hour('2009-07-30 04:17:52');
--日期转分钟函数: minute
select minute('2009-07-30 04:17:52');
--日期转秒函数: second
select second('2009-07-30 04:17:52');
--日期转周函数: weekofyear 返回指定日期所示年份第几周
select weekofyear('2009-07-30 04:17:52');

5.3 数学函数 

----Mathematical Functions 数学函数-------------
--取整函数: round  返回double类型的整数值部分 (遵循四舍五入)
select round(3.1415926);
--指定精度取整函数: round(double a, int d) 返回指定精度d的double类型
select round(3.1415926,4);
--向下取整函数: floor
select floor(3.1415926);
select floor(-3.1415926);
--向上取整函数: ceil
select ceil(3.1415926);
select ceil(-3.1415926);
--取随机数函数: rand 每次执行都不一样 返回一个0到1范围内的随机数
select rand();
--指定种子取随机数函数: rand(int seed) 得到一个稳定的随机数序列
select rand(3);

5.4  二进制函数

--二进制函数:  bin(BIGINT a)
select bin(18);
--进制转换函数: conv(BIGINT num, int 原进制, 转换后进制)
select conv(17,10,16);
--绝对值函数: abs
select abs(-3.9);

5.5 集合函数

-------Collection Functions 集合函数--------------
--集合元素size函数: size(Map<K.V>) size(Array<T>)
select size(`array`(11,22,33));
select size(`map`("id",10086,"name","zhangsan","age",18));

--取map集合keys函数: map_keys(Map<K.V>)
select map_keys(`map`("id",10086,"name","zhangsan","age",18));

--取map集合values函数: map_values(Map<K.V>)
select map_values(`map`("id",10086,"name","zhangsan","age",18));

--判断数组是否包含指定元素: array_contains(Array<T>, value)
select array_contains(`array`(11,22,33),11);
select array_contains(`array`(11,22,33),66);

--数组排序函数:sort_array(Array<T>)
select sort_array(`array`(12,2,32));

5.6  条件函数

-----Conditional Functions 条件函数------------------
--使用之前课程创建好的student表数据
select * from student limit 3;

describe function extended isnull;

--if条件判断: if(boolean testCondition, T valueTrue, T valueFalseOrNull)
select if(1=2,100,200);
select if(sex ='男','M','W') from student limit 3; --如果sex=男则返回M否则为w

--空判断函数: isnull( a )
select isnull("allen");
select isnull(null);

--非空判断函数: isnotnull ( a )
select isnotnull("allen");
select isnotnull(null);

--空值转换函数: nvl(T value, T default_value)
select nvl("allen","itcast");
select nvl(null,"itcast");

--非空查找函数: COALESCE(T v1, T v2, ...)
--返回参数中的第一个非空值;如果所有值都为NULL,那么返回NULL
select COALESCE(null,11,22,33);
select COALESCE(null,null,null,33);
select COALESCE(null,null,null);

--条件转换函数: CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END
select case 100 when 50 then 'tom' when 100 then 'mary' else 'tim' end;
select case sex when '男' then 'male' else 'female' end from student limit 3;

5.7 类型转换函数

----Type Conversion Functions 类型转换函数-----------------
--任意数据类型之间转换:cast
select cast(12.14 as bigint);
select cast(12.14 as string);
select cast("hello" as int);

5.8 数据脱敏函数

----Data Masking Functions 数据脱敏函数------------
--mask
--将查询回的数据,大写字母转换为X,小写字母转换为x,数字转换为n。
select mask("abc123DEF");
select mask("abc123DEF",'-','.','^'); --自定义替换的字母

--mask_first_n(string str[, int n]
--对前n个进行脱敏替换
select mask_first_n("abc123DEF",4);

--mask_last_n(string str[, int n])
select mask_last_n("abc123DEF",4);

--mask_show_first_n(string str[, int n])
--除了前n个字符,其余进行掩码处理
select mask_show_first_n("abc123DEF",4);

--mask_show_last_n(string str[, int n])
select mask_show_last_n("abc123DEF",4);

--mask_hash(string|char|varchar str)
--返回字符串的hash编码。
select mask_hash("abc123DEF");

5.9 其他杂项函数

----- Misc. Functions 其他杂项函数---------------

--如果你要调用的java方法所在的jar包不是hive自带的 可以使用add jar添加进来
--hive调用java方法: java_method(class, method[, arg1[, arg2..]])
select java_method("java.lang.Math","max",11,22);

--反射函数: reflect(class, method[, arg1[, arg2..]])
select reflect("java.lang.Math","max",11,22);

--取哈希值函数:hash
select hash("allen");

--current_user()、logged_in_user()、current_database()、version()

--SHA-1加密: sha1(string/binary)
select sha1("allen");

--SHA-2家族算法加密:sha2(string/binary, int)  (SHA-224, SHA-256, SHA-384, SHA-512)
select sha2("allen",224);
select sha2("allen",512);

--crc32加密:
select crc32("allen");

--MD5加密: md5(string/binary)
select md5("allen");

九、函数高阶应用(面试)

1. explode函数

--使用explode函数对champion_year进行拆分 俗称炸开
select explode(champion_year) from the_nba_championship;

2. Lateral View侧视图

 lateral view侧视图基本语法如下

select …… from 
tabelA lateral view UDTF(xxx)别名 as col1,col2, col..,.

select * from the_nba_championship a lateral view explode(champion_year) b as year;

3. 行列转换

3.1 多行转单列

select col1,col2, collect_list(col3)
from row2col1 group by col1,col2;

 

3.2 单列转多行 

select col1, col2, cl3
from col2row2 a lateral view explode(split(col3, ',')) b as cl3;

4. json格式处理

get_json_object json_tuple

--get_json_object
select
    --获取设备名称
    get_json_object(json,"$.device") as device,
    --获取设备类型
    get_json_object(json,"$.deviceType") as deviceType,
    --获取设备信号强度
    get_json_object(json,"$.signal") as signal,
    --获取时间
    get_json_object(json,"$.time") as stime
from tb_json_test1;

--json_tuple
--单独使用
select
    --解析所有字段
    json_tuple(json,"device","deviceType","signal","time") as (device,deviceType,signal,stime)
from tb_json_test1;


--搭配侧视图使用
select
    json,device,deviceType,signal,stime
from tb_json_test1
         lateral view json_tuple(json,"device","deviceType","signal","time") b
         as device,deviceType,signal,stime;

JSONSerde 

--JsonSerDe
--创建表
create table tb_json_test2
(
    device     string,
    deviceType string,
    signal     double,
    `time`     string
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS TEXTFILE; --表示将表中的数据以文本文件的形式存储在HDF

load data local inpath '/hivedata/device.json' into table tb_json_test2;

select *
from tb_json_test2;

5. 窗口函数

5.1 聚合函数

5.2 window 子句

SELECT id, score,
sum(score) over (PARTITION by id) as a1, --ROWS BETWEEN  1到最后
sum(score) over (PARTITION by id order by score) as a2, -- range BETWEEN  1到当前 重复数据并列
sum(score) over (PARTITION by id order by score ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as a3, --ROWS BETWEEN  1到当前
sum(score) over (PARTITION by id order by score ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as a4, --ROWS BETWEEN  1到最后
sum(score) over (PARTITION by id order by 1) as a5
from itcast.t_student;

SELECT id, score,
sum(score) over (PARTITION by id order by score RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as b1,
sum(score) over (PARTITION by id order by score RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) as b2
from t_student;

5.3 窗口排序

-----窗口排序函数
SELECT cookieid,
       createtime,
       pv,
       RANK() OVER (PARTITION BY cookieid ORDER BY pv desc)       AS rn1,
       DENSE_RANK() OVER (PARTITION BY cookieid ORDER BY pv desc) AS rn2,
       ROW_NUMBER() OVER (PARTITION BY cookieid ORDER BY pv DESC) AS rn3
FROM website_pv_info
WHERE cookieid = 'cookie1';


--需求:找出每个用户访问pv最多的Top3 重复并列的不考虑
select * from
(select cookieid,
       createtime,
       pv,
       row_number() over (partition by cookieid order by pv desc ) as fn
from website_pv_info) A
where fn<4;

--把每个分组内的数据分为3桶
SELECT
    cookieid,
    createtime,
    pv,
    NTILE(3) OVER(PARTITION BY cookieid ORDER BY createtime) AS rn2
FROM website_pv_info
ORDER BY cookieid,createtime;

--需求:统计每个用户pv数最多的前3分之1天。
--理解:将数据根据cookieid分 根据pv倒序排序 排序之后分为3个部分 取第一部分
SELECT * from
(SELECT
     cookieid,
     createtime,
     pv,
     NTILE(3) OVER(PARTITION BY cookieid ORDER BY pv DESC) AS rn
 FROM website_pv_info) tmp where rn =1;

5.4 窗口分析函数

-----------窗口分析函数----------
--LAG
SELECT cookieid,
       createtime,
       url,
       ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
       LAG(createtime,1,'1970-01-01 00:00:00') OVER(PARTITION BY cookieid ORDER BY createtime) AS last_1_time,
       LAG(createtime,2) OVER(PARTITION BY cookieid ORDER BY createtime) AS last_2_time
FROM website_url_info;


--LEAD
SELECT cookieid,
       createtime,
       url,
       ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
       LEAD(createtime,1,'1970-01-01 00:00:00') OVER(PARTITION BY cookieid ORDER BY createtime) AS next_1_time,
       LEAD(createtime,2) OVER(PARTITION BY cookieid ORDER BY createtime) AS next_2_time
FROM website_url_info;

--FIRST_VALUE
SELECT cookieid,
       createtime,
       url,
       ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
       FIRST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS first1
FROM website_url_info;

--LAST_VALUE
SELECT cookieid,
       createtime,
       url,
       ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
       LAST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS last1
FROM website_url_info;

十、性能调优

1. 文件存储格式

 

1.1 行存储 

1.2 列存储

2. 数据压缩

2.1 建表压缩

在实际开发中,可以根据需求选择不同的文件格式并且搭配不同的压缩算法。可以得到更好的存储效果。
--不指定压缩格式 代表什么呢?
--orc 存储文件默认采用ZLIB 压缩。比 snappy 压缩的小
STORED AS or;--2.78M

--以ORC格式存储 不压缩
STORED As orc tblproperties("orc.compress""NONE”); --7.69M

--以ORC格式存储 使用snappy压缩
STORED AS orc tblproperties("orc.compress"="SNAPPY");--3.78M

3. 通用调优

3.1 Fetch抓取机制

3.2 MR 本地模式

3.3 JOIN 优化

reduce join 

 

map join 

#是否开启自动转为mapjoin 在满足条件的情况下 默认true
hive.auto.convert.join=true

Hive老版本
#如果参与的一个表大小满足条件 转换为map join
hive.mapjoin.sma1ltable.filesize=25000000

Hive2.0之后版本
#是否启用基于输入文件的大小,将reduce join转化为Map join的优化机制。
假设参与join的表(或分区)有N个,如果打开这个参数,
并且有N-1个表(或分区)的大小总和小于hive.auto.convert.join.noconditionaltask,
size参数指定的值,那么会直接将join转为Map join。

hive.auto.convert.join.noconditionaltask=true
hive.auto.convert.join.noconditionaltask.size=512000000

3.4. 数据倾斜优化

 

3.5 MapReduce Task并行度调整

3.6 执行计划explain

;