目录
数据类型
内部表 外部表
分区表 分桶表
创建表的三种方式
存储格式
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稍差
存储过程中,记录会被横向切分成多个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是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储
资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
提供了多种索引,row group index、bloom filter index。
ORC可以支持复杂的数据结构(比如Map等)
ORC中的特定的序列化与反序列化操作可以使ORC file writer根据数据类型进行写出。
count(1),count(*),count(某字段)
count(*):所有行进行统计,包括NULL行
count(1):所有行进行统计,包括NULL行
count(column):对column中非Null进行统计
count(distinct column):对column中非Null进行去重统计
添加字段: 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相当于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')
例子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,}$