Hive分区(Partition)
分区主要用于提高性能
分区列的值将表划分为一个个的文件夹
查询时语法使用"分区"列和常规列类似
查询时Hive会只从指定分区查询数据,提高查询效率
注:
由于Hive实际是存储在HDFS上的抽象,Hive的一个分区名对应一个目录名,子分区名就是子目录名,并不是一个实际字段。
所以可以这样理解,当我们在插入数据的时候指定分区,其实就是新建一个目录或者子目录,或者在原有的目录上添加数据文件。
分为静态分区和动态分区
示例演示
一、静态分区
创建数据,准备用性别分区
打开hive创建表
hive> create table userinfo(
> userid string,
> username string,
> brithday string
> )
> partitioned by (sex string)
> row format delimited fields terminated by ','
> stored as textfile;
OK
Time taken: 0.247 seconds
hive> desc userinfo; //查看表结构
OK
userid string
username string
brithday string
sex string
# Partition Information //分区信息
# col_name data_type comment
sex string
用load直接传输数据并用静态分区(错误)
hive> load data local inpath '/opt/software/info.csv' overwrite into table userinfo partition (sex='male');
注意
这里会存在问题,这里并不是真正的分区,而是强行把所有数据传入分区,并把对应的属性在展示时全改为分区的属性,而实际属性未发生改变。在hdfs上查询文件,其真实内容如下图
删除表数据重新开始
先在hdfs上创建文件夹,存放数据文件
hive> !hdfs dfs -mkdir -p /wh;
hive> !hdfs dfs -put /opt/software/info.csv /wh;
创建原始表存放数据,路径为刚刚上传地址
hive> create table ods_user (
> userid string,
> username string,
> brithday string,
> sex string
> )
> row format delimited fields terminated by ','
> location '/wh'
> ;
通过这张表向分区表中插入数据
在插入数据时注意 ,后面select中不要将分区的属性也查询插入。按照分区的属性分别插入
hive> insert into userinfo partition(sex='male') select userid,username,brithday from ods_user where sex='male';
hive> insert into userinfo partition(sex='female') select userid,username,brithday from ods_user where sex='female';
插入结束后可以查看网页192.168.73.39:50070页面
二、动态分区
如果用上述的静态分区,插入的时候必须首先要知道有什么分区类型,而且每个分区都要写一个insert语句,在某些场景下还是比较麻烦。使用动态分区可解决以上问题,其可以根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。
创建表
hive> create table myusers(
> userid string,
> username string,
> brithday string
> )
> partitioned by (sex string)
> row format delimited fields terminated by ','
> stored as textfile;
使用动态分区需设定属性
hive> set hive.exec.dynamic.partition=true; //开启
hive> set hive.exec.dynamic.partition.mode=nonstrict; //设置分区模式为非严格模式
从原始表中直接插入数据
hive> insert into myusers partition(sex) select * from ods_user;
成功显示,可以看出它直接根据sex的两个属性自动分区
网页显示