一、表的分区
大数据开发数据量较大,在进行数据查询计算时,需要对数据进行拆分,提升的查询速度
1-1 单个分区
单个分区是创建单个目录
-- 创建表指定分区,对原始数据进行分区保存 create table new_tb_user(id int,name string,age int,gender int,create_time date )partitioned by (gender_p int) row format delimited fields terminated by ','; select * from new_tb_user; -- 将原始数据表的数据写入新的分区表中 -- 静态写入分区数据 需要手动自己指定分区数值 -- insert into new_tb_user partition(gender_p=0) select * from tb_user where gender=0 -- 动态写入分区数据 -- 可以指定一个字段数据,根据字段数据内容进行分区 set hive.exec.dynamic.partition.mode=nonstrict; insert into new_tb_user partition(gender_p) select id,name,age,gender,create_time,gender from tb_user; desc new_tb_user; desc tb_user;
1-2 多个分区
多个分区可以将数据拆分多个目录存储
create table new2_tb_user(id int,name string,age int,gender int,create_time date )partitioned by (y string,m string,d string) row format delimited fields terminated by ','; select * from new2_tb_user; insert into new2_tb_user partition(y,m,d) select id,name,age,gender,create_time,year(create_time),month(create_time),day(create_time) from tb_user limit 10;
注意点
1-分组字段不能和表中字段重名
2-动态分区数据写入时,select中字段顺序要和分区表中字段顺序一致
3-分区字段是在最后,所以select中的分区数据指定也放在最后
1-3 分区的增删改查
-- 创建一个分区表 create table tb_student(id int,name string,gender string,age int,cls string )partitioned by (cls_p string) row format delimited fields terminated by ','; -- show查看分区表的分区信息 show partitions tb_student; -- 生成分区数据信息 -- 方式1 通过insert数据导入,生成对应的分区数据 -- 方式2 通过add方法直接指定分区,指定后会在对应表目录下生成分区目录 alter table tb_student add partition(cls_p='CS'); show partitions tb_student; select * from tb_student; -- 修改分区名 ALTER TABLE tb_student PARTITION(cls_p='CS') RENAME TO PARTITION(cls_p='CS2'); -- 删除分区 alter table tb_student drop partition(cls_p='CS')
二、表的分桶
分区 将数据拆分不同目录下存储
分桶 将数据拆分成不同文件进行存储
无论是分区,还是分桶,本质都是对数据的拆分存储,作用是为了提升查询的效率
2-1 分桶创建
使用分桶时,一般都是已经存在了一个原始数据表,为了提升原始数据速度,将原始数据在重新写入一个分桶表
create table tb_user_buckets(id int,name string,age int,gender int,create_time date ) -- clustered by 指定按照哪个字段的数据进行数据的拆分 into 2 buckets 指定拆分的数量clustered by(gender) into 2 buckets row format delimited fields terminated by ','; -- 将原始数据表的数据写入到分桶表 insert into tb_user_buckets select * from tb_user limit 100; create table tb_user_buckets_new(id int,name string,age int,gender int,create_time date ) -- clustered by 指定按照哪个字段的数据进行数据的拆分 into 2 buckets 指定拆分的数量clustered by(gender) into 3 buckets row format delimited fields terminated by ','; insert into tb_user_buckets_new select * from tb_user limit 100;
2-2 分桶原理说明
数据按照hash取余的方式进行拆分,写入到不同的文件中
hash(分桶字段)%分桶数=余数
2-3 分桶主要使用场景
多表关联,为了提升多表关联的查询效率,可以将关联的表数据按照相同的关联字段,进行分桶,保持分桶个数一致,或是倍数关系,可以将系统数据放在同一个余数文件中,提升了关联效率
分桶还可以进行随机采样
可以通过随机采样减少计算量
三、数据的文件的读取和写入
hive在对hdfs上的文件数据进行读取和写入数据时,会调用的mapreudce的方法有两类
该方法叫做序列化器方法
如果使用delimited: 表示底层默认使用的Serde类:LazySimpleSerDe类来处理数据。
如果使用serde:表示指定其他的Serde类来处理数据,支持用户自定义SerDe类。
3-1 默认序列化器 delimited
在进行表定义时指定row format delimited
指定处理不同数据的方法
fields terminated by 字段的处理方法 指定如何分割字段 collection items terminated by 指定字段中数组的分割分割方式 map keys terminated by 指定map的数据分割方式这几个方法主要对文件数据读取时,方便区分不同数据内容
I-array类型数据
对读取的数据中符合数组拆分数据转为数组
1,张三,篮球-足球,20 2,李四,羽毛球-乒乓球,20
-- 创建一个用户表 create table tb_user_new(id int,name string,hobby string,age int )row format delimited fields terminated by ','; select * from tb_user_new; -- 将兴趣字段 转为数组格式保存 [篮球,足球] create table tb_user_new_array(id int,name string,hobby array<string>,age int )row format delimited fields terminated by ','-- 指定字段的分割符 collection items terminated by '-'; -- 指定字段中数组数据分割符 select * from tb_user_new_array;
II-struct类型数据
1,张三#20#男
1-先按照逗号拆分数据
2-在将张三#20#男 按照数组拆分 [张三,20,男]
3-在对数组中的数据转为map形式 {'name':张三,'age':20,'gender':男}
create table tb_user_new_struct(id int,`user` struct<name:string,age:int,gender:string> )row format delimited fields terminated by ',' collection items terminated by '#'; -- [张三,20,男] select * from tb_user_new_struct;
III-map类型数据
1,孙悟空,53,西部大镖客:288-大圣娶亲:888-全息碎片:0-至尊宝:888-地狱火:1688 2,鲁班七号,54,木偶奇遇记:288-福禄兄弟:288-黑桃队长:60-电玩小子:2288-星空梦想:0 3,后裔,53,精灵王:288-阿尔法小队:588-辉光之辰:888-黄金射手座:1688-如梦令:1314 4,铠,52,龙域领主:288-曙光守护者:1776 5,韩信,52,飞衡:1788-逐梦之影:888-白龙吟:1188-教廷特使:0-街头霸王:888
1-按照field进行字段分割 分隔符是,
2-按照数组进行字段分割 分隔符是 - ['西部大镖客:288','大圣娶亲:888',全息碎片:0,至尊宝:888,地狱火:1688]
3-在将数组的key:value结构数据转为map {'西部大镖客':288,'大圣娶亲':888}
id | name | blood | skin |
---|---|---|---|
1 | 孙悟空 | 53 | {'西部大镖客':288,'大圣娶亲':888} |
3-2 自定义序列化器
可以使用自定义序列化器中提供jar包完成对json数据的处理
可以将json文件中的数据key最为字段,将value值解析为对应的行数据
{"movie":"1293","rate":"5","timeStamp":"978298261","uid":"2"}
-- {"movie":"1293","rate":"5","timeStamp":"978298261","uid":"2"} create table tb_movie(movie string,rate string,`timeStamp` string,uid string )row format serde 'org.apache.hive.hcatalog.data.JsonSerDe'; -- 指定三方的序列化器 解析json文件 select * from tb_movie;
四、内置函数
是hive提供的函数方法,方便对不同类型的字段数据进行操作
4-1 字符串操作函数
-
计算字符串长度
-
length(字段)
-
-
字符串拼接
-
concat
-
concat_ws
-
-
字符串切割
-
split(字段,'切割的字符')
-
-
字符串截取
-
substr(create_time,起始的字符位置数,截取的字符个数)
-
-
字符串替换
-
regexp_replace(字段,'原始字符','替换的新字符')
-
select * from tb_stu; -- 计算字符串长度 统计字符个数 select name,length(name) from tb_stu; -- 拼接多个字符换 没有拼接字符 select name,gender,concat(name,gender) from tb_stu; select name,gender,concat_ws(':',name,gender) from tb_stu; -- 切割 切割后的数据是数组 select create_time,split(create_time,'-') from tb_stu; -- 数组取值 select create_time,split(create_time,'-')[0] from tb_stu; -- 截取 取字符串中指定长度的字符数据 -- substr(create_time,起始的字符位置数,截取的字符个数) select create_time,substr(create_time,1,4) from tb_stu; -- 替换 select create_time,regexp_replace(create_time,'-','/') from tb_stu; -- 方法嵌套使用 -- trim 去除字符串的前后空格 ' 张三 ' select create_time,substr(trim(name),1,4) from tb_stu
4-2 数值操作函数
select 1+1; select 1-1; select 1*10; select 2%5; select round(3.12); select round(3.1214,2); select round(3.1294,2); -- 向上取整数 select ceil(3.14); -- 向下取整数 select floor(3.14); -- 次方计算 select pow(2,3);
4-3 条件判断函数
-- if判断 -- if(判断条件,成立返回的结果,不成立返回的结果) 单个条件判断 select gender,if(gender=0,'男','女') from tb_user; -- 多个分类条件判断 case when -- 10-18 少年 18-40 青年 40-65 中年 大于 65 老年 select age,casewhen age <=18 then '少年'when age >18 and age <=40 then '青年'when age >40 and age <=65 then '中年'when age >65 then '老年'end as age_new from tb_user; -- 查看方法的使用形式 desc function extended nullif;