Hive基础

目录

数据类型

内部表 外部表

分区表 分桶表

创建表的三种方式

存储格式

ORC(Optimized Row Columnar)

ORC的数据存储方式

ORC具有以下一些优势:

常用命令

count命令

alter命令

COALESCE函数

时间操作函数

json_tuple函数

行转列、列转行

中位数函数

排序函数

修复表

正则


数据类型

1、简单数据类型:

(1)、整型,如:tinyint,smallint,int,bigint。

(2)、字符串类型,如:string。

(3)、时间戳类型。

(4)、日期型。

(5)、浮点型,如:float,double。

2、复杂数据类型:

(1)、映射,关键字:map。

(2)、结构体,关键字:struct。

(3)、数组,关键字:array。

3、null类型:在hive中底层是用'\N'来存储的,可以通过alter table tableName set serdeproperties('serialization.null.format'='a')来设置。

内部表 外部表

内部表:加载数据到hive所在的hdfs目录,删除时,元数据和数据文件都删除

外部表:不加载数据到hive所在的hdfs目录,删除时,只删除表结构。

未被external修饰的是内部表,被external修饰的为外部表; 内部表数据由Hive自身管理,外部表数据由HDFS管理;

建表语句
内部表 create table [IF NOT EXISTS] 表名;
外部表 create EXTERNAL table [IF NOT EXISTS] 表名;

分区表 分桶表

分区表

分区为 HDFS 上表目录的子目录,数据按照分区存储在子目录中。比如将日志文件按天进行分区,从而保证数据细粒度的

划分,使得查询性能得到提升。

在 Hive 中可以使用 PARTITIONED BY 子句创建分区表。

分桶表

分区提供了一个隔离数据和优化查询的可行方案,但是并非所有的数据集都可以形成合理的分区,

分区的数量也不是越多越好,过多的分区条件可能会导致很多分区上没有数据。同时 Hive 会限制动态分区可以

创建的最大分区数,用来避免过多分区文件对文件系统产生负担。

鉴于以上原因,Hive 还提供了一种更加细粒度的数据拆分方案:分桶表 (bucket Table)。分桶表会将指定列

的值进行哈希散列,并对 bucket(桶数量)取余,然后存储到对应的 bucket(桶)中。

创建

1、
    开启分桶功能  set hive.enforce.bucketing=true;
    设置桶的数量  set mapreduce.job.reduces=3;
    创建分桶表   create table course (c_id string,c_name string,t_id string) clustered by(c_id) into 3 buckets row format delimited fields terminated by ‘\t’;
​
2.
    分桶的参数,主要使用SMB-Mapjoin
    set hive.optimize.bucketmapjoin = true;
    set hive.auto.convert.sortmerge.join=true;
    set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
    set hive.optimize.bucketmapjoin.sortedmerge = true; 
​
        注意:分桶字段必须出现在表已有的字段内。
        --使用时候不能是倾斜表,否则完犊子。适合量大不倾斜的表;
        上面两种参数方案没有实践,但是应该可以以方案二的参数为准

分桶逻辑: 分桶表会将指定列的值进行哈希散列,并对 bucket(桶数量)取余,然后存储到对应的 bucket(桶)中。 分区在 HDFS上的表现形式是一个目录, 分桶是一个单独的文件

作用:提高join效率和用于数据取样。

        提高join效率:将join关联的字段作为分桶字段。相同的数据汇入到一个桶内,在join时直接读取桶内的所有数据,不用全表扫描。

        数据取样:将数据编号作为分桶字段,与分桶数量取余。这样可以讲数据打散,分到不同的桶内。那么每个桶内的数据包含各个“阶段”的数据。

创建表的三种方式

直接建表

CREATE TABLE IF NOT EXISTS $ads_device_cluster_all_data_tmp(
     device string  COMMENT 'device'
    ,lon    double  COMMENT '经度'
    ,lat    double  COMMENT '纬度'
    ,time   string  COMMENT '时间'
    ,weight string  COMMENT '权重'
)
PARTITIONED BY (
    month STRING COMMENT '日期',
    stage   string  COMMENT '计算阶段',
    flag    string  COMMENT 'flag')
STORED AS ORC TBLPROPERTIES (
    'orc.compress' = 'SNAPPY', 'orc.compress.size'='8192'
)

抽取(as)建表

CREATE TABLE mytest_tmp1 AS
SELECT  *
FROM FDM_SOR.mytest_deptaddr
WHERE statis_date = '20180229';

like建表

CREATE TABLE mytest_tmp like FDM_SOR.mytest_deptaddr;

存储格式

Text,Sequence,RCfile,ORC,Parquet,AVRO

Text:可读性好,占用磁盘空间大(文本 行式存储),使用但是不常用

Sequence:Hadoop API提供的一种二进制文件,以key,value的形式序列化带文件中(二进制 行式存储)

RCfile:面向列的存储格式(二进制 列式存储,压缩)

ORC:RCfile的升级版,优化了压缩、查询(二进制列式存储,压缩),文件可切分,支持复杂的数据结构,常用的压缩格式Lzip,Snappy,压缩、解压一般是冲突的在

Parquet:存储嵌套式数据,如json;支持更多编码;可以很sparkSQL很好的结合。列式存储高压缩(二进制列式存储,高压缩)压缩和查询性能比ORC稍差

ORC(Optimized Row Columnar)

ORC的数据存储方式

存储过程中,记录会被横向切分成多个stripes,每个stripes内的数据以列为单位进行存储,

所有列的内容保存在同一个文件中,通过配置对block压缩,设置HDFS的每个block存储ORC文件

的一个stripe。每个stripe的默认大小为256MB,相对于RCFile每个4MB的stripe而言,更大的stripe

使ORC的数据读取更加高效。

首先根据行组分割整个表,在每一个行组内进行按列存储

元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗

目前也被Hive SQL、Spark SQL、Presto等查询引擎支持

设置stripe的只保存在一个block上的话,如果当前block上的剩余空间不足以存储下一个strpie,

ORC的writer接下来会将数据打散保存在block剩余的空间上,直到这个block存满为止。这样,下

一个stripe又会从下一个block开始存储。

ORC具有以下一些优势:

ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。

文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储

资源,查询任务的输入数据量减少,使用的MapTask也就减少了。

提供了多种索引,row group index、bloom filter index。

ORC可以支持复杂的数据结构(比如Map等)

ORC中的特定的序列化与反序列化操作可以使ORC file writer根据数据类型进行写出。

常用命令

count命令

count(1),count(*),count(某字段)

count(*):所有行进行统计,包括NULL行

count(1):所有行进行统计,包括NULL行

count(column):对column中非Null进行统计

count(distinct column):对column中非Null进行去重统计

alter命令

添加字段:        alter table st.st_app_ad_type add columns(advertisement_id STRING) cascade;              
添加字段到指定位置 
    添加字段:alter table dm_mid_master.st_app_ad_type     add columns(rdid STRING) cascade; 
    移动到指定位:alter table dm_mid_master.st_app_ad_type     change rdid rdid string after muid ;  
修改表名:
    alter table table_name rename to new_table_name;
            --内部表修改后表名、库名、路径都会改的
修改字段类型:
    Alter table dws.dws_app_income  change  click_cnt  click_cnt  decimal(10,2) cascade;
修改字段名称:
    ALTER TABLE log_online CHANGE wpusingnum register_day string;
修改表和字段注释:
    ALTER TABLE table_name SET TBLPROPERTIES('comment' = '这是表注释!')
    ALTER TABLE table_name CHANGE COLUMN muid muid_new STRING COMMENT '这里是列注释!'
查看分区:
    show partitions dws.dws_app_retention_new;
删除分区:
    alter table table_name drop if exists partition(par_col=col_name)
内部表转外部表
    alter table xm_testA set TBLPROPERTIES ('EXTERNAL = true')
外部表转换内部表
    alter table dws.dws_app_retention_new set tblproperties('EXTERNAL'='false');
注意:
分区表修改必加cascade
alter table default.testparquet add columns(c8 string) cascade;
分区表新增字段默认模式为RESTRICT(即不修改元数据),cascade则同步修改元数据,这样才会重新刷新历史数据时添加的字段才会有值,不然重刷新历史数据新添加的字段数据都为null。生产环境对于分区表修改建议直接加cascade。

COALESCE函数

COALESCE字符函数,功能:返回其参数中的第一个非空表达式

COALESCE相当于nvl(nvl(x,y),1)

nvl:如果第一个值非空取默认值,默认值是自己赋值上去的是个常数。支持两个参数。

时间操作函数

1.yyyy-mm-dd ---转化--->  yyyymmdd
select from_unixtime(unix_timestamp('2021-12-15','yyyy-mm-dd'),'yyyymmdd')
2.yyyymmdd ---转化--->  yyyy-mm-dd
select from_unixtime(unix_timestamp('20211215','yyyymmdd'),'yyyy-mm-dd')

json_tuple函数

 例子1: select json_tuple(json,'movie','rate','time','userid') as (movie_id,rate,time,user_id) 
 例子2:
 SELECT kv_sc,
         json_tuple(kv_sc,'text','desc','img') AS (kv_sc_text,kv_sc_DESC,kv_sc_img)
 FROM ods.ods_str_json_app_ad_orc
 WHERE kv_sc IS NOT NULL
 LIMIT 100

行转列、列转行

行转列
SELECT 
    udi,concat_ws(',',collect_set(P.day)) as tag_col 
FROM rt_src_free_new_device_detail_tmp AS P
GROUP BY P.udi
列转行:
SELECT proj,uid,venue_arr,venue_arr_temp
FROM kuaizip.rt_user_venues 
LATERAL VIEW explode(venue_arr) venue_arr_temp AS venue_arr_temp
WHERE DAY='2019-10-15'

中位数函数

 percentile(BIGINT col, p)
 select percentile(score,<0.2,0.4>) from lxw_dual;取0.2,0.4位置的数据,中位数应该用0.5
 中位数,  percentile(int(price), 0.5) as mid_price
95分位数	percentile(int(price), 0.95) as mid_price

排序函数

row_number():从1开始,按照顺序,生成分组内记录的序列,row_number()的值不会存在重复,当排序的值相同时,按照表中记录的顺序进行排列;通常用于获取分组内排序第一的记录;获取一个session中的第一条refer等。
rank():生成数据项在分组中的排名,排名相等会在名次中留下空位。
dense_rank():生成数据项在分组中的排名,排名相等会在名次中不会留下空位。

first_value取分区内排序后,截止到当前行,第一个值
last_value分组内排序后,截止到当前行,最后一个值

LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值
LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)

修复表

可以使用msck repair table xxxxx命令修复!
set hive.msck.path.validation=ignore;

正则

小数保留5位,不进位:
	select  regexp_extract('-42.87054','((-)?[0-9]*.[0-9]{0,5})',0)
	等价与
	select FLOOR(42.8704*100000)/100000

匹配由数字和26个英文字母组成的字符串: ^[A-Za-z0-9]+$  
匹配由数字、26个英文字母或者下划线组成的字符串:^w+$   '^[0-9a-zA-Z_]{1,}$ 

你可能感兴趣的:(#,数据计算工具,hive,hadoop,大数据)