分区表 分区是将一个表或索引物理地分解为多个更小、更可管理的部分。 分区对应用透明,即对访问数据库的应用而言,逻辑上讲只有一个表或一个索引(相当于应用“看到”的只是一个表或索引),但在物理上这个表或索引可能由数十个物理分区组成。
在 Hadoop 中,Hive 分区表通常以特定的目录结构来存储。 每个分区对应一个独立的目录,目录名通常包含分区列的值。数据文件会存储在相应的分区目录下。
分桶表 •分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分。
•分桶是将数据集分解成更容易管理的若干部分的另一个技术。
•分区针对的是数据的存储路径;分桶针对的是数据文件。
分桶策略:Hive的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方 式决定该条记录存放在哪个桶当中。
分区表
分桶表
划分依据
分区列的离散值(目录分割)
分桶列的哈希值(文件分割)
数量灵活性
分区数量可动态新增
桶数量固定(创建时指定)
优化目标
减少扫描范围(过滤查询)
优化 Join 和抽样(哈希分片)
实践练习 1.清洗excel文件 超市数据.xlsx 为文本文件,按照分区字段对文件进行拆分 ps: 浮点数精确小数点后2位,不需要有表头和index ,数据分隔符不能是逗号 数据清洗脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import pandas as pdimport osdf = pd.read_excel('超市数据.xlsx' ) output_dir = '超市数据_分区' os.makedirs(output_dir, exist_ok=True ) float_columns = ['销售额' , '折扣' , '利润' ] for category in df['类别' ].unique(): category_df = df.loc[df['类别' ] == category].copy() for col in float_columns: if col in category_df.columns: category_df[col] = category_df[col].round (2 ) file_path = os.path.join(output_dir, f'{category} .txt' ) category_df.to_csv(file_path, sep='\t' , na_rep='nan' , header=False , index=False ) print (f"数据已按类别清洗并拆分至目录: {output_dir} " )
2.创建一个分区表,做分桶 clustered by (id ) into 2 buckets, 将文本文件分别 插入到分区中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 create table supermarket_p1 (id string, ord_id string comment '订单 ID' , ord_date string comment '订单日期' , exch_date string comment '发货日期' , exch_type string comment '邮寄方式' , cust_id string comment '客户 ID ' , cust_name string comment '客户名称' , d_type string comment '细分' , city string comment '城市' , prov string comment '省/自治区' , country string comment'国家' , area string comment '地区' , pro_id string comment '产品 ID' , type1 string comment '类别' , type2 string comment '子类别' , pro_name string comment '产品名称' , sales float comment '销售额' , count1 int comment '数量 ' , discount float comment '折扣 ' , profit float comment '利润' ) partitioned by (c_type1 string) clustered by (id) into 2 buckets row format delimited fields terminated by '\t'
上传数据到hdfs系统
1 2 3 4 hdfs dfs -mkdir -p /user/hive/warehouse/supermarket/data hdfs dfs -put 办公用品.txt /user/hive/warehouse/supermarket/data hdfs dfs -put 技术.txt /user/hive/warehouse/supermarket/data hdfs dfs -put 家具.txt /user/hive/warehouse/supermarket/data
插入数据
1 2 3 4 5 6 7 8 load data inpath '/user/hive/warehouse/supermarket/data/办公用品.txt' into table supermarket_p1 partition (c_type1= 'bgyp' )load data inpath '/user/hive/warehouse/supermarket/data/技术.txt' into table supermarket_p1 partition (c_type1= 'jishu' )load data inpath '/user/hive/warehouse/supermarket/data/家具.txt' into table supermarket_p1 partition (c_type1= 'jiajv' )
3.创建一个 按订单时间分区的分区表 (year_ string, month_ string)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 create table supermarket_p2 (id string, ord_id string comment '订单 ID' , ord_date string comment '订单日期' , exch_date string comment '发货日期' , exch_type string comment '邮寄方式' , cust_id string comment '客户 ID ' , cust_name string comment '客户名称' , d_type string comment '细分' , city string comment '城市' , prov string comment '省/自治区' , country string comment'国家' , area string comment '地区' , pro_id string comment '产品 ID' , type1 string comment '类别' , type2 string comment '子类别' , pro_name string comment '产品名称' , sales float comment '销售额' , count1 int comment '数量 ' , discount float comment '折扣 ' , profit float comment '利润' ) partitioned by (year_ string, month_ string) row format delimited fields terminated by '\t'
动态分区配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 set hive.exec.dynamic.partition= true set hive.exec.dynamic.partition.mode= nonstrictset hive.exec.max.dynamic.partitions= 1000 set hive.exec.max.dynamic.partitions.pernode= 100 set hive.exec.max.created.files= 100000 set hive.error.on.empty.partition= false set hive.support.quoted.identifiers= none
4.将第二部的数据 使用动态分区的方法 导入到 第三步的表中
1 2 3 insert into supermarket_p2 partition (year_,month_)select p1.* ,date_format(ord_date,"yyyy"),date_format(ord_date,"MM")from (select `(c_type1)?+ .+ ` from supermarket_p1) p1