一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)

一、分区的定义

分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹, Hive 中的分区就是分目录 ,把一个大的数据集根据业务需要分割成小的数据集。
在查询时通过 where 子句中的表达式选择查询所需要的指定的分区,这样的查询效率
会提高很多,所以我们需要把常常用在where 语句中的字段指定为表的分区字段。
而分区又分为静态分区、动态分区两种。

二、静态分区、动态分区对比

静态分区与动态分区的主要区别在于静态分区是手动指定,是编译时进行分区。支持load和insert两种插入方式。适合于分区数少、分区名可以明确的数据

而动态分区是通过数据来进行判断,是在SQL执行时进行分区。只支持inset这一种插入方式。需要先开启动态设置。实际项目里按日期进行分区的数据一般都是动态分区

三、HDFS数据准备

(一)HDFS文件后缀名以日期区分

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第1张图片

(二)查看数据样式

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第2张图片

四、Hive建普通外部表  不分区

(一)建表语句

create external table if not exists ods_evaluation(
    device_no  string         COMMENT '设备编号',
    cycle  int                COMMENT '评价数据周期',
    lane_num  int,
    create_time  timestamp    COMMENT '创建时间',
    lane_no int               COMMENT '车道编号',
    volume int                COMMENT '车道内过停止线流量(辆)',
    queue_len_max float       COMMENT '车道内最大排队长度(m)',
    sample_num int            COMMENT '评价数据计算样本量',
    stop_avg int              COMMENT '车道内平均停车次数(次)',
    delay_avg float           COMMENT '车道内平均延误时间(s)',
    stop_rate float           COMMENT '车道内一次通过率',
    travel_dist float         COMMENT '车道内检测行程距离(m)',
    travel_time_avg float     COMMENT '车道内平均行程时间'
)
comment '评价数据表'
row format delimited fields terminated by ','
stored as  textfile  location '/rtp/evaluation'
tblproperties("skip.header.line.count"="1")  ;

(二)结果展示  共9076条数据

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第3张图片

五、静态分区

(一)建表语句

create external table if not exists ods_evaluation_static(
    device_no  string         COMMENT '设备编号',
    cycle  int                COMMENT '评价数据周期',
    lane_num  int,
    create_time  timestamp    COMMENT '创建时间',
    lane_no int               COMMENT '车道编号',
    volume int                COMMENT '车道内过停止线流量(辆)',
    queue_len_max float       COMMENT '车道内最大排队长度(m)',
    sample_num int            COMMENT '评价数据计算样本量',
    stop_avg int              COMMENT '车道内平均停车次数(次)',
    delay_avg float           COMMENT '车道内平均延误时间(s)',
    stop_rate float           COMMENT '车道内一次通过率',
    travel_dist float         COMMENT '车道内检测行程距离(m)',
    travel_time_avg float     COMMENT '车道内平均行程时间'
)
comment '评价历史数据表 静态分区'
partitioned by (day string)   --分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
row format delimited fields terminated by ','
tblproperties("skip.header.line.count"="1")  ;

注意点:

1、指定的分区字段不能是表中已经存在的数据  我这边分区字段为day  而表中没有这个字段

2、建表没有指定文件路径

(二)加载数据(有坑

注意:从HDFS中加载数据到Hive,如果直接load HDFS中的数据到Hive中,那么原HDFS数据文件就会消失在原路径,而是去了一个hive的新地方。直接load,这种行为它类似于剪切,而不是我们所希望的复制文件。 这是一个坑!!!

所以如果我们希望既可以load数据到hive,还能够保存HDFS的原文件,那么必须采用迂回策略,从HDFS先到本地,再load到Hive。比如加载HDFS中2023-05-09的数据

先从HDFS到l本地  /opt/hdfs_rtp/

[root@hurys22 conf]# hdfs dfs -get /rtp/evaluation/evaluation2023-05-09.csv /opt/hdfs_rtp/

从本地加载到Hive

load data local inpath '/opt/hdfs_rtp/evaluation2023-05-09.csv'
into  table  ods_evaluation_static
partition(day='2023-05-09');

(三)查看分区

show partitions ods_evaluation_static;

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第4张图片

(四)查看数据

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第5张图片

 六、动态分区

(一)建表语句

create external table if not exists ods_evaluation_trends(
    device_no  string         COMMENT '设备编号',
    cycle  int                COMMENT '评价数据周期',
    lane_num  int,
    create_time  timestamp    COMMENT '创建时间',
    lane_no int               COMMENT '车道编号',
    volume int                COMMENT '车道内过停止线流量(辆)',
    queue_len_max float       COMMENT '车道内最大排队长度(m)',
    sample_num int            COMMENT '评价数据计算样本量',
    stop_avg int              COMMENT '车道内平均停车次数(次)',
    delay_avg float           COMMENT '车道内平均延误时间(s)',
    stop_rate float           COMMENT '车道内一次通过率',
    travel_dist float         COMMENT '车道内检测行程距离(m)',
    travel_time_avg float     COMMENT '车道内平均行程时间'
)
comment '评价历史数据表 动态分区'
partitioned by (day string)
row format delimited fields terminated by ',';

注意:由于动态分区不是load文件,所以建表时不需要截掉第一行数据 tblproperties("skip.header.line.count"="1")

(二)开启动态分区

--开启动态分区功能(默认 true,开启)
set hive.exec.dynamic.partition=true;
--设置为非严格模式   nonstrict 模式表示允许所有的分区字段都可以使用动态分区
set hive.exec.dynamic.partition.mode=nonstrict;
--在每个执行 MR 的节点上,最大可以创建多少个动态分区
set hive.exec.max.dynamic.partitions.pernode=1000;
--在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
set hive.exec.max.dynamic.partitions=1500;

(三)动态加载数据(insert overwrite)

insert  overwrite table ods_evaluation_trends partition(day)
select device_no, cycle, lane_num, create_time, lane_no, volume, queue_len_max, sample_num, stop_avg, delay_avg, stop_rate,
       travel_dist, travel_time_avg,date(create_time) day
from ods_evaluation;

注意insert overwrite的用法

insert into 与 insert overwrite 都可以向hive表中插入数据,但是insert into是直接追加到目前表中数据的尾部,而insert overwrite则会重写数据,即先删除数据,再写入数据。如果存在分区的情况,insert overwrite只重写当前分区

(四)查看动态分区

show  partitions ods_evaluation_trends;

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第6张图片

 (五)查看数据

一百一十一、Hive——从HDFS到Hive的数据导入(静态分区、动态分区)_第7张图片

你可能感兴趣的:(Hive,hive,hdfs,hadoop)