Hive基础3

一、表的分区

大数据开发数据量较大,在进行数据查询计算时,需要对数据进行拆分,提升的查询速度

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,
       case
        when 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;
​
相关推荐
计艺回忆路42 分钟前
Hive自定义函数(UDF)开发和应用流程
hive·自定义函数·udf
万能小锦鲤15 小时前
《大数据技术原理与应用》实验报告三 熟悉HBase常用操作
java·hadoop·eclipse·hbase·shell·vmware·实验报告
天翼云开发者社区21 小时前
数据治理的长效机制
大数据·数据仓库
王小王-1231 天前
基于Hadoop与LightFM的美妆推荐系统设计与实现
大数据·hive·hadoop·大数据美妆推荐系统·美妆商品用户行为·美妆电商
一切顺势而行1 天前
hadoop 集群问题处理
大数据·hadoop·分布式
万能小锦鲤2 天前
《大数据技术原理与应用》实验报告七 熟悉 Spark 初级编程实践
hive·hadoop·ubuntu·flink·spark·vmware·实验报告
项目題供诗2 天前
Hadoop(二)
大数据·hadoop·分布式
Leo.yuan2 天前
ETL还是ELT,大数据处理怎么选更靠谱?
大数据·数据库·数据仓库·信息可视化·etl
万能小锦鲤2 天前
《大数据技术原理与应用》实验报告五 熟悉 Hive 的基本操作
hive·hadoop·ubuntu·eclipse·vmware·实验报告·hiveql
張萠飛2 天前
flink sql如何对hive string类型的时间戳进行排序
hive·sql·flink