Hive中分区表与分桶表的操作

目录

分区表

 一级分区表

知识点

 示例

多级分区

知识点

 示例

分区表的操作

示例

hadoop_hive文档

分桶表

 重要参数

基础分桶表

知识点

示例

分桶表排序

知识点

示例

分桶原理

分区表和分桶表区别


分区表

Hive中分区表与分桶表的操作_第1张图片

分区表特点/好处: 需要产生分区目录, 查询的时候使用分区字段筛选数据,避免全表扫描从而提升查询效率

效率上注意: 如果分区表,在查询数据的时候没有使用分区字段去筛选数据,效率不变

分区字段名注意: 分区字段名不能和原有字段名重复,因为分区字段名要作为字段拼接到表后

 一级分区表

知识点

创建分区表: create table [external] table [if not exists] 表名(字段名 字段类型,字段名 字段类型,...) partition by(分区字段名 分区字段类型)...;

自动生成分区目录并插入数据: load data [local] inpath '文件路径' into table 分区表名 partition (分区字段名='值'');

注意:如果加local 后面文件路径应该是linux本地路径,如果没有加那么就是hdfs文件路径

 示例

-- 2.多级分区表
-- 创建表
create table more_part_order(
    oid string,
    name string,
    price float,
    num int
) partitioned by ( year string,month string,day string)
row format delimited fields terminated by ' ';
-- 插入数据
load data inpath '/source/order202251.txt'
    into table more_part_order
    partition (year='2022',month='2022-05',day='2022-05-01');
load data inpath '/source/order2023415.txt'
    into table more_part_order
    partition (year='2023',month ='2023-04',day ='2023-04-15');
load data inpath '/source/order202351.txt'
    into table more_part_order
    partition (year='2023',month ='2023-05',day ='2023-05-01');
load data inpath '/source/order202352.txt'
    into table more_part_order
    partition (year='2023',month ='2023-05',day ='2023-05-02');
-- 验证数据
select * from more_part_order;
-- 分区表的好处:避免全表扫描,提升查询效率
-- 需求: 统计2023年商品总销售额
select sum(price*num) from more_part_order; -- 4618
-- 需求: 统计2023年5月份商品总销售额
select sum(price*num) from more_part_order where month='2023-05'; --128
-- 需求: 统计2023年5月1日的商品总销售额
select sum(price*num) from more_part_order where day='2023-05-01'; --78

多级分区

知识点

创建分区表: create [external] table [if not exists] 表名(字段名 字段类型 , 字段名 字段类型 , ... )partitioned by (一级分区字段名 分区字段类型, 二级分区字段名 分区字段类型 , ...) ;

自动生成分区目录并插入数据: load data [local] inpath '文件路径' into table 分区表名 partition (一级分区字段名='值',二级分区字段名='值' , ...);

注意: 如果加local后面文件路径应该是linux本地路径,如果没有加那么就是hdfs文件路径

 示例

-- 2.多级分区表
-- 创建表
create table more_part_order(
    oid string,
    name string,
    price float,
    num int
) partitioned by ( year string,month string,day string)
row format delimited fields terminated by ' ';
-- 插入数据
load data inpath '/source/order202251.txt'
    into table more_part_order
    partition (year='2022',month='2022-05',day='2022-05-01');
load data inpath '/source/order2023415.txt'
    into table more_part_order
    partition (year='2023',month ='2023-04',day ='2023-04-15');
load data inpath '/source/order202351.txt'
    into table more_part_order
    partition (year='2023',month ='2023-05',day ='2023-05-01');
load data inpath '/source/order202352.txt'
    into table more_part_order
    partition (year='2023',month ='2023-05',day ='2023-05-02');
-- 验证数据
select * from more_part_order;
-- 分区表的好处:避免全表扫描,提升查询效率
-- 需求: 统计2023年商品总销售额
select sum(price*num) from more_part_order; -- 4618
-- 需求: 统计2023年5月份商品总销售额
select sum(price*num) from more_part_order where month='2023-05';
-- 需求: 统计2023年5月1日的商品总销售额
select sum(price*num) from more_part_order where day='2023-05-01';

分区表的操作

添加分区:alter table 分区表名 add partition (分区字段名='值',...);

删除分区:alter table 分区表名 drop partition (分区字段名='值',...);

修改分区名:alter table 分区表名 partition (分区字段名='旧值',...)rename to partition(分区字段名='新值')

查看所有分区:show partitions 分区表名;

同步/修复分区:msck repair table 分区表名;

示例

-- 添加分区(本质在hdfs上创建分区目录)
alter table one_part_order add partition (year=2024);
alter table more_part_order add partition (year=2024,month='2024-05',day='2024-05-01');
-- 修改分区(本质在hdfs上修改分区目录名)
alter table one_part_order partition (year=2024) rename to partition (year=2025);
-- 原2024目录及2024目录下的分区目录2024-05被保留,实际是分区目录2024-05-01被改名新创建了一个2025/2025-05/2025-05-01的分区目录
alter table more_part_order partition (year=2024,month='2024-05',day='2024-05-01')
    rename to partition (year=2025,month='2025-05',day='2025-05-01');
-- 查看所有分区
show partitions one_part_order;
show partitions more_part_order;
-- 删除分区
--分区目录2025被删除
alter table one_part_order drop partition (year=2025); -- 2025被删除
alter table more_part_order drop partition (year=2023,month='2023-05',day='2023-05-01'); --2023-05-01被删除
alter table more_part_order drop partition (year=2023,month='2023-05');-- 2023-05 被删除
alter table more_part_order drop partition (year=2023); -- 2023被删除
-- 如果在hdfs上创建符合分区目录格式的文件夹,可以使用msck repair修复
-- 举例:手动创建一个year=2033目录
msck repair table one_part_order;
msck repair table more_part_order;
-- 修复后再次查看所有分区
show partitions one_part_order;
show partitions more_part_order;

hadoop_hive文档

hive文档: https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
hdfs文档: https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
yarn文档: https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
mr文档: https://hadoop.apache.org/docs/stable/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml

分桶表

Hive中分区表与分桶表的操作_第2张图片

分桶表特点/好处: 需要产生分桶文件, 查询的时候特定操作上提升效率(过滤,join,分组 以及 抽样)

效率上注意:  如果分桶表,在查询数据的时候没有使用分桶字段去筛选数据,效率不变

分桶字段名注意: 分桶字段名必须是原有字段名, 因为分桶需要根据对应字段值取余数把余数相同的数据放到同一个分桶文件中

 重要参数

-- 默认开启,hive2.x版本已经被移除
set hive.enforce.bucketing; -- 查看未定义因为已经被移除
set hive.enforce.bucketing=true; -- 修改

-- 查看reduce数量
-- 参数优先级: set方式 > hive文档 > hadoop文档
set mapreduce.job.reduces; -- 查看默认-1,代表自动根据桶数量匹配reduce数量
set mapreduce.job.reduces=3; -- 设置参数

基础分桶表

知识点

创建基础分桶表:  
create [external] table [if not exists] 表名(
    字段名 字段类型
)
clustered by (分桶字段名)
into 桶数量 buckets ;

示例

-- 1.创建基础分桶表,要求分3个桶
create table course(
    id int,
    subject string,
    name string
)clustered by (id) into 3 buckets
row format delimited fields terminated by '\t';
-- 加载数据
load data inpath '/source/course.txt' into table course;
-- 验证数据
select  * from course;

分桶表排序

知识点

创建基础分桶表,然后桶内排序:   
create [external] table [if not exists] 表名(
    字段名 字段类型
)
clustered by (分桶字段名)
sorted by(排序字段名 asc|desc)   # 注意:asc升序(默认) desc降序
into 桶数量 buckets ;

示例

-- 1.创建基础分桶表,要求分3个桶,桶内根据id降序
create table course_sort(
    id int,
    subject string,
    name string
)clustered by (id) sorted by (id desc )into 3 buckets
row format delimited fields terminated by '\t';
-- 加载数据
load data inpath '/source/course.txt' into table course_sort;
-- 验证数据
select  * from course_sort;

分桶原理

分桶原理:
如果是数值类型分桶字段: 直接使用数值对桶数量取模   
如果是字符串类型分桶字段: 底层会使用hash算法计算出一个数字然后再对桶数量取模

Hash: Hash是一种数据加密算法,其原理我们不去详细讨论,我们只需要知道其主要特征:同样的值被Hash加密后的结果是一致的
举例: 字符串“sisi”被Hash后的结果是3530540(仅作为示意),那么无论计算多少次,字符串“sisi”的结果都会是3530540。
计算余数: hash('sisi')%3==2 
注意: 同样的数据得到的结果一致,如’sisi’ hash取模结果是2,无论计算多少次,它的取模结果都是2

分区表和分桶表区别

分区表
    创建表的时候使用关键字: partition by (分区字段名 分区字段类型)
    分区字段名注意事项: 是一个新的字段,需要指定类型,且不能和其他字段重名
    分区表好处: 使用分区字段作为条件的时候,底层直接找到对应的分区目录,能够避免全表扫描,提升查询效率
    分区表最直接的效果: 在hfds表目录下,分成多个分区目录(year=xxxx,month=xx,day=xx)
    不建议直接上传文件在hdfs表根路径下: 分区表直接不能识别对应文件中数据,因为分区表会找分区目录下的数据文件
    使用load方式加载hdfs中文件: 本质是移动文件到对应分区目录下

分桶表
    创建表的时候使用关键字: clustered by (分桶字段名) into 桶数量 buckets
    分桶字段名注意事项: 是指定一个已存在的字段,不需要指定类型
    分桶表好处: 使用分桶字段做抽样等特定操作的时候,也能提升性能效率
    分桶表最直接的效果: 在hdfs表目录或者分区目录下,分成多个分桶文件(000000_0,000001_0,000002_0...)
    不建议直接上传文件在hdfs表根路径下: 分桶表可以识别对应文件中数据,但是并没有分桶效果,也是不建议的
    使用load方式加载hdfs中文件: 本质是复制数据到各个分桶文件中

你可能感兴趣的:(hive,hadoop,数据仓库)