Hive 1.2.1 分区和分捅

1. 借鉴

Hive学习笔记——Hive中的分桶
Hive分区和分桶(0925)
HIVE表索引,分区和分桶的区别

2. 开始

基于前篇文章的建表语句,来分别看下分区表和分桶表。

分区表

分区表对应HDFS上独立的文件夹,一个文件夹表示一个分区

创建分区表

我们基于以下数据创建分区表 <数据文件可以这里下载>

# 2020-03-18日 创建订单
# 文件为hotel_checkin_log-2020-03-18.log
10271563,2020-03-19,14:00,2020-03-20,12:00,02:55:22,1431259675035954008
00277553,2020-03-19,12:00,2020-03-22,12:00,12:00:00,1124559675462631493
02371493,2020-03-19,17:00,2020-03-19,12:00,09:20:00,1634659676964192299

# 2020-03-19日 创建订单
# 文件为hotel_checkin_log-2020-03-19.log
10271563,2020-03-20,14:00,2020-03-21,12:00,02:55:22,1124759681900888144
00277553,2020-03-20,12:00,2020-03-22,12:00,12:00:00,1234759682320318549
02371493,2020-03-20,17:00,2020-03-21,12:00,09:20:00,1236559684014817343

# 2020-03-20日 创建订单
# 文件为hotel_checkin_log-2020-03-20.log
10271563,2020-03-21,14:00,2020-03-23,12:00,02:55:22,1123659685898059853
00277553,2020-03-22,12:00,2020-03-25,12:00,12:00:00,1213559689173811267
02371493,2020-03-22,17:00,2020-03-23,12:00,09:20:00,1133659694081146884

我们根据数据构建以下表结构:

create table hotel_checkin_log(
  code string,
  checkin_date string,
  checkin_time string,
  checkout_date string,
  checkout_time string,
  order_time string,
  uId string
)
partitioned by (order_date string)
row format delimited fields terminated by ',';
加载数据

此时加载数据和之前的略有区别,主要是需要指定分区。此时分区列不包含在原始数据中,在加载数据的时候需要手动指定,所以数据一定要规划好

load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-18.log' into table db_company.hotel_checkin_log partition(order_date='2020-03-18');
load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-19.log' into table db_company.hotel_checkin_log partition(order_date='2020-03-19');
load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-20.log' into table db_company.hotel_checkin_log partition(order_date='2020-03-20');

如果没有指定分区会出现以下错误

ValidationFailureSemanticException Partition spec xxx contains non-partition columns
查询分区表

不指定分区

select * from hotel_checkin_log;

指定分区

select * from db_company.hotel_checkin_log where order_date = '2020-03-18';
查询分区明细
show partitions  hotel_checkin_log;

明细如下:

partition
order_date=2020-03-18
order_date=2020-03-19
order_date=2020-03-20
Time taken: 0.061 seconds, Fetched: 3 row(s)
创建分区

注意:这里的创建分区,不是有了一个order_date分区,再创建一个order_time分区,而是为order_date添加分区,我们是可以指定多个分区,后面我们再说。

# 创建一个分区
alter table db_company.hotel_checkin_log add partition(order_date='2020-03-21');

# 创建多个分区
alter table db_company.hotel_checkin_log add partition(order_date='2020-03-22') partition(order_date='2020-03-23');

我们此时看下分区明细

partition
order_date=2020-03-18
order_date=2020-03-19
order_date=2020-03-20
order_date=2020-03-21
order_date=2020-03-22
order_date=2020-03-23
Time taken: 0.059 seconds, Fetched: 6 row(s)
删除分区

可以看到删除分区和创建分区基本类似,区别在于

  1. add 关键字替换为drop关键字
  2. 批量删除时以,分隔,批量添加时以空格分隔
# 删除单个分区
alter table db_company.hotel_checkin_log drop partition(order_date='2020-03-21');

# 删除多个分区
alter table db_company.hotel_checkin_log drop partition(order_date='2020-03-22'), partition(order_date='2020-03-23');
创建多级分区

上面我们说了创建分区,是在一个分区列下面增加分区,那如果我想有两个分区列呢

create table hotel_checkin_log_gather(
  code string,
  checkin_date string,
  checkin_time string,
  checkout_date string,
  checkout_time string,
  order_time string,
  uId string
)
partitioned by (order_date string, gather int)
row format delimited fields terminated by ',';

加载数据

load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-18.log' into table db_company.hotel_checkin_log_gather partition(order_date='2020-03-18', gather = 1);
load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-19.log' into table db_company.hotel_checkin_log_gather partition(order_date='2020-03-19', gather = 1);
load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-20.log' into table db_company.hotel_checkin_log_gather partition(order_date='2020-03-20', gather = 1);

指定了两个分区,则在加载数据时都需要指定,否则会出现未知分区的错误提示

分区与数据加载

上面我们都是加载数据到hdfs时并指定分区。
我们知道,hive的数据是存放在hdfs中的,有时我们需要先将数据直接放到hdfs的目录中然后再加载。

方式1

① 创建了分区表
② 手动在hdfs中创建分区文件夹,并上传数据文件(在这一步可以验证以下,分区表是查询不出来数据的)
③ 进行关联修复
④ 再次查询有数据了

下面我们依次来操作一下

  1. 我们使用hotel_checkin_log这个表,目前它有三个分区(order_date=2020-03-18,order_date=2020-03-19,order_date=2020-03-20)

  2. 我们创建一个2020-03-31的分区并上传文件

    #创建文件夹
    hdfs dfs -mkdir -p /hive.db/company/hotel_checkin_log/order_date=2020-03-31
    # 上传文件
    hdfs dfs -put /opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-03-31.log /hive.db/company/hotel_checkin_log/order_date=2020-03-31
    
  3. 查询一下数据【没有是正常的】

    select * from db_company.hotel_checkin_log where order_date = '2020-03-31'
    
  4. 修复关联

    msck repair table db_company.hotel_checkin_log;
    
  5. 再次查询即可看到数据了

方式2

① 创建了分区表
② 手动在hdfs中创建分区文件夹,并上传数据文件(在这一步可以验证以下,分区表是查询不出来数据的)
③ 创建分区

下面我们依次来操作一下

  1. 我们使用hotel_checkin_log这个表,目前它有四个分区(order_date=2020-03-18,order_date=2020-03-19,order_date=2020-03-20, order_date=2020-03-31)

  2. 我们创建一个2020-04-01的分区并上传文件

    #创建文件夹
    hdfs dfs -mkdir -p /hive.db/company/hotel_checkin_log/order_date=2020-04-01
    # 上传文件
    hdfs dfs -put /opt/envs/datas/hotel_checkin_log/hotel_checkin_log-2020-04-01.log /hive.db/company/hotel_checkin_log/order_date=2020-04-01
    
  3. 查询一下数据【没有是正常的】

    select * from db_company.hotel_checkin_log where order_date = '2020-03-31'
    
  4. 创建分区

    alter table hotel_checkin_log add partition(order_date='2020-04-01');
    
  5. 再次查询即可看到数据了

分桶表

分桶表对应HDFS上多个文件,一个文件表示一个桶。分桶将整个数据内容按照某列属性的值的hash值进行分桶,比如我们这里的按照code进行分桶,分为4个桶,就是对code属性值的hash值对4取摸,按照取模结果对数据分桶。

创建分区表

我们基于以下数据创建分区表 <数据文件可以这里下载>

创建分区表后导入数据有一个限制,需要从中间表导入,否则数据并没有在多个分捅。为了将数据填充到桶中,必须使用insert语句而不是load语句,因为它(load)不根据元数据定义验证数据(只将文件复制到文件夹)

我们根据数据构建以下表结构:

# 创建临时表
create TEMPORARY table tmp_hotel_checkin_bucket_log(
  code string,
  checkin_date string,
  checkin_time string,
  checkout_date string,
  checkout_time string,
  order_time string,
  uId string
)
row format delimited 
fields terminated by ',';

# 创建正式表
create table hotel_checkin_bucket_log(
  code string,
  checkin_date string,
  checkin_time string,
  checkout_date string,
  checkout_time string,
  order_time string,
  uId string
)
clustered by(code) 
into 4 buckets
row format delimited 
fields terminated by ',';

查看分捅数量 [Num Buckets 属性]

desc formatted hotel_checkin_bucket_log;
OK
col_name        data_type       comment
# col_name              data_type               comment             
                 
code                    string                                      
checkin_date            string                                      
checkin_time            string                                      
checkout_date           string                                      
checkout_time           string                                      
order_time              string                                      
uid                     string                                      
                 
# Detailed Table Information             
Database:               db_company               
Owner:                  root                     
CreateTime:             Mon Jun 22 11:38:56 UTC 2020     
LastAccessTime:         UNKNOWN                  
Protect Mode:           None                     
Retention:              0                        
Location:               hdfs://hadoop01:9000/hive.db/company/hotel_checkin_bucket_log    
Table Type:             MANAGED_TABLE            
Table Parameters:                
        COLUMN_STATS_ACCURATE   true                
        numFiles                1                   
        totalSize               863                 
        transient_lastDdlTime   1592826192          
                 
# Storage Information            
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe       
InputFormat:            org.apache.hadoop.mapred.TextInputFormat         
OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat       
Compressed:             No                       
Num Buckets:            4                  
Bucket Columns:         [code]                   
Sort Columns:           []                       
Storage Desc Params:             
        field.delim             ,                   
        serialization.format    ,                   
Time taken: 0.05 seconds, Fetched: 36 row(s)

加载数据至中间表

load data local inpath '/opt/envs/datas/hotel_checkin_log/hotel_checkin_log.log' into table tmp_hotel_checkin_bucket_log;

在插入数据之前,需要在hive命令行设置以下参数,另外在hive本地模式下强制分桶会报错,因为只有一个reducer,所以要么需要集群模式,要么使用本地模式,不强制分桶,结果只有一个桶

# 设置强制分桶
set hive.enforce.bucketing=true;
 # 这里我创建的是4个桶,或者设置为-1,表示不限制,依据建表中的分桶数量
set mapred.reduce.tasks = 4;

从中间表导入数据

insert into table hotel_checkin_bucket_log select code, checkin_date, checkin_time, checkout_date, checkout_time,  order_time, uId from tmp_hotel_checkin_bucket_log;

3. 大功告成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354