什么网站做电子相册比加快,用php做的网站怎么上传,中山权威发布,有道云笔记 wordpress目录
一、分区概念产生背景
二、分区表特点
三、分区表类型
3.1 单分区
3.2 多分区
四、动态分区与静态分区
4.1 静态分区【静态加载】
4.1.1 操作演示
4.2 多重分区
4.2.1 操作演示
4.3 分区数据动态加载
4.3.1 分区表数据加载 -- 动态分区
4.3.2 操作演示
五、…目录
一、分区概念产生背景
二、分区表特点
三、分区表类型
3.1 单分区
3.2 多分区
四、动态分区与静态分区
4.1 静态分区【静态加载】
4.1.1 操作演示
4.2 多重分区
4.2.1 操作演示
4.3 分区数据动态加载
4.3.1 分区表数据加载 -- 动态分区
4.3.2 操作演示
五、分桶表
5.1 分桶表概念
5.2 分桶规则说明
5.2.1 分桶基本规则
5.3 分桶完整语法树
5.4 分桶表操作演示
5.4.1 创建表
5.4.2 使用分桶表好处 一、分区概念产生背景 使用hive对表进行查询时比如select * from t_user where name lihua hive执行这条sql的时候一般会扫描整个表的数据我们知道全表扫描的效率是很低的尤其是对于hive这种最终数据的查询要走hdfs文件全表扫描效率就更低了。 事实上在很多情况下业务中需要查询的数据并不需要全表扫描而是能够预知查询的数据在一定的区域中基于这个前提hive在建表的时候就引入了partition分区的概念。对应建表语法树位置如下 二、分区表特点 分区表指的是在创建表时指定的partition的分区空间如果需要创建有分区的表需要在create表的时候调用可选参数partitioned by 一个表可以拥有一个或者多个分区每个分区以文件夹的形式单独存在表文件夹的目录下 表和列名不区分大小写 分区是以字段的形式存在于表结构中通过desc formatted table命令可以查看到字段存在但该字段不存放实际的数据内容仅仅是分区的表示 三、分区表类型 分区表根据建表时分区字段数分为单分区表和多分区表如下 3.1 单分区
单分区就是说在表文件夹目录下只有一级文件夹目录建表的时候PARTITIONED BY里面的字段只有一个如下按照省份单分区
create table t_user_province (id int, name string,age int
) partitioned by (province string); 3.2 多分区
另外一种是多分区表文件夹下出现多文件夹嵌套模式建表的时候可以根据业务需要指定多个分区字段如下为三分区表按省份、市、县分区
create table t_user_province_city_county (id int, name string,age int
) partitioned by (province string, city string,county string); 四、动态分区与静态分区 4.1 静态分区【静态加载】
静态分区指的是分区的属性值是由用户在加载数据的时候手动指定的语法
load data [local] inpath filepath into table tablename partition(分区字段分区值...);
注意 Local参数用于指定待加载的数据是位于本地文件系统还是HDFS文件系统 4.1.1 操作演示 创建分区表 创建一张分区表t_all_hero_part以role角色作为分区字段
create table t_all_hero_part(id int,name string,hp_max int,mp_max int,attack_max int,defense_max int,attack_range string,role_main string,role_assist string
) partitioned by (role string)
row format delimited
fields terminated by \t;
执行上面的sql进行分区表的创建 可以看到在这张表中多出来了一个role的分区字段 上传本地数据到服务器目录 上传下面的本地测试数据文件到指定目录 将数据加载到hive 使用下面的命令加载本地数据文件到hive表
load data local inpath /usr/local/soft/hivedata/archer.txt into table t_all_hero_part partition(rolesheshou);
load data local inpath /usr/local/soft/hivedata/assassin.txt into table t_all_hero_part partition(rolecike);
load data local inpath /usr/local/soft/hivedata/mage.txt into table t_all_hero_part partition(rolefashi);
load data local inpath /usr/local/soft/hivedata/support.txt into table t_all_hero_part partition(rolefuzhu);
load data local inpath /usr/local/soft/hivedata/tank.txt into table t_all_hero_part partition(roletanke);
load data local inpath /usr/local/soft/hivedata/warrior.txt into table t_all_hero_part partition(rolezhanshi); 执行过程 检查数据可以看到数据成功映射到分区表中重点注意最后那一列正是分区字段 同时在HDFS目录下的数据展示如下结构 静态分区表的数据存放很有规律可循外层以分区名称为目录内层才是当前这个分区的具体数据文件 这个与普通的非分区表的区别一目了然就不再赘述了通过这种直观的方式可以进一步对分区表的概念做如下理解 分区的概念提供了一种将Hive表数据分离为多个文件/目录的方法 不同分区对应着不同的文件夹同一分区的数据存储在同一个文件夹下 查询过滤的时候只需要根据分区值找到对应的文件夹扫描本文件夹下本分区下的文件即可避免全表数据扫描 这种指定分区查询的方式叫做分区裁剪 此时如果使用下面的这条sql进行查询就可以先定位到分区然后只查询这个分区下的这个数据文件这样一来就不用走全表扫描效率大大提升了
select * from t_all_hero_part where rolesheshou and hp_max 6000; 4.2 多重分区
通过建表语句中关于分区的相关语法可以发现Hive支持多个分区字段
PARTITIONED BY (partition1 data_type, partition2 data_type,….) 多重分区下分区之间是一种递进关系可以理解为在前一个分区的基础上继续分区从HDFS的角度来看就是文件夹下继续划分子文件夹。比如把全国人口数据首先根据省进行分区然后根据市进行划分如果你需要甚至可以继续根据区县再划分此时就是3分区表。 4.2.1 操作演示 创建两个分区表 创建一个双分区表按照省份与城市划分
create table t_user_province_city (id int, name string,age int) partitioned by (province string, city string); 创建一个三分区表按照省、市、县划分
create table t_user_province_city_county (id int, name string,age int) partitioned by (province string, city string,county string); 4.3 分区数据动态加载 上面使用load的方式手动指定分区数据的方式也叫做静态分区静态加载,实际使用中如果创建的分区非常多就意味着要使用load命令加载很多次这样效率必然很低这时就可以考虑使用hive的动态分区 4.3.1 分区表数据加载 -- 动态分区 所谓动态分区指的是分区的字段值是基于查询结果参数位置自动推断出来的。核心语法就是insertselect 启用hive动态分区需要在hive会话中设置两个参数
#是否开启动态分区功能
set hive.exec.dynamic.partitiontrue;
#指定动态分区模式分为nonstick非严格模式和strict严格模式
#strict严格模式要求至少有一个分区为静态分区
set hive.exec.dynamic.partition.modenonstrict;
4.3.2 操作演示
创建一张新的分区表执行动态分区插入sql建表语句如下
create table t_all_hero_part_dynamic(id int,name string,hp_max int,mp_max int,attack_max int,defense_max int,attack_range string,role_main string,role_assist string
) partitioned by (role string)
row format delimited
fields terminated by \t; 在执行上面的sql之前需要在当前会话下设置如下参数
set hive.exec.dynamic.partitiontrue;
set hive.exec.dynamic.partition.modenonstrict; 创建完成后执行下面的sql将上一张表的数据进行导入
insert into table t_all_hero_part_dynamic partition(role) select tmp.*,tmp.role_main from t_all_hero tmp;
执行的时间可能有点长 查看hdfs上该动态表的目录可以看到也是按照预期的分区字段将数据文件做了划分 分区表的注意事项 分区表不是建表的必要语法规则是一种优化手段表可选 分区字段不能是表中已有的字段不能重复 分区字段是虚拟字段其数据并不存储在底层的文件中 分区字段值的确定来自于用户价值数据手动指定静态分区或者根据查询结果位置自动推断动态分区 Hive支持多重分区也就是说在分区的基础上继续分区划分更加细粒度 五、分桶表 5.1 分桶表概念
分桶表也叫做桶表叫法源自建表语法中bucket单词是一种用于优化查询而设计的表类型分桶表对应的数据文件在底层会被分解为若干个部分通俗来说就是被拆分成若干个独立的小文件在分桶时要指定根据哪个字段将数据分为几桶几个部分 5.2 分桶规则说明 5.2.1 分桶基本规则
桶编号相同的数据会被分到同一个桶当中
Bucket number hash_function(bucketing_column) mod num_buckets分桶编号 哈希方法分桶字段 取模 分桶个数 hash_function取决于分桶字段bucketing_column的类型 如果是int类型hash_function(int) int; 如果是其他比如bigint,string或者复杂数据类型hash_function比较棘手将是从该类型派生的某个数字比如hashcode值 5.3 分桶完整语法树
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type [COMMENT col_comment], ... ]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED|SERDE serde_name WITH SERDEPROPERTIES (property_nameproperty_value,...)]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_nameproperty_value, ...)]; 分桶关键参数说明 CLUSTERED BY (col_name)表示根据哪个字段进行分 INTO N BUCKETS表示分为几桶也就是几个部分 需要注意的是分桶的字段必须是表中已经存在的字段 最简单的分桶sql
CREATE [EXTERNAL] TABLE [db_name.]table_name
[(col_name data_type, ...)]
CLUSTERED BY (col_name)
INTO N BUCKETS; 5.4 分桶表操作演示
需求有如下数据文件 文件内容解读 内容展示了美国2021-1-28号各个县county的新冠疫情累计案例信息包括确诊病例和死亡病例 字段含义count_date统计日期,county县,state州,fips县编码code,cases累计确诊病例,deaths累计死亡病例 5.4.1 创建表
分桶的字段一定要是表中已经存在的字段
无字段排序的分桶表
根据state字段把数据分为5桶建表语句如下
CREATE TABLE t_usa_covid19_bucket(count_date string,county string,state string,fips int,cases int,deaths int)
CLUSTERED BY(state) INTO 5 BUCKETS; 带有字段排序的分桶表
根据state字段分为5桶 每个桶内根据cases确诊病例数倒序排序
CREATE TABLE t_usa_covid19_bucket_sort(count_date string,county string,state string,fips int,cases int,deaths int)
CLUSTERED BY(state)
sorted by (cases desc) INTO 5 BUCKETS; 创建成功后查看hdfs可以看到表的相关数据目录 注意向hive的分桶表导入数据时不能再直接使用hdfs的命令直接加载数据文件到表的目录需要通过insert select的方式 为了导入数据到上面创建的分桶表先创建一个普通的表建表sql如下
CREATE TABLE t_usa_covid19(count_date string,county string,state string,fips int,cases int,deaths int)
row format delimited fields terminated by ,; 上传数据文件到该表
hdfs dfs -put ./us-covid19-counties.dat /user/hive/warehouse/test.db/t_usa_covid19
执行成功后检查该表数据可以看到数据加载成功 使用insertselect语法将数据加载到分桶表中
insert into t_usa_covid19_bucket select * from t_usa_covid19; 看到这个map-reduce任务完成之后再去检查分桶表数据此时数据就加载进去了 到HDFS上查看t_usa_covid19_bucket底层数据结构可以发现数据被分为了5个部分并且从结果可以发现分桶字段一样的数据就一定被分到同一个桶中 接下来做一个测试吧基于分桶字段state查询来自于New York州的数据既然数据按照state(州)进行了分桶查询的时候就不再需要进行全表扫描过滤底层来说查询的时候将根据分桶的规则hash_function(New York) mod 5计算出分桶编号查询指定分桶里面的数据 就可以找出结果 此时是分桶扫描而不是全表扫描
select * from t_usa_covid19_bucket where stateNew York;
从查询速度来说还是很快的 5.4.2 使用分桶表好处 基于分桶字段查询时减少全表扫描 分桶之后如果按照分桶字段进行筛选数据量明显减少了就可以避免全表的扫描而提升查询效率 JOIN时可以提高MR程序效率减少笛卡尔积数量 正常两表关联查询比如 select a.* from a join b on a.id b.id ...这样的查询时如果不走分桶表其底层一定是按照笛卡尔积的数量进行数据扫描与查询而对于分桶表来说如果on后面的字段正好是分桶字段的话查询的数据就会在确定的桶中进行数据量减少了所以笛卡尔积数量也会大大减少 使用分桶表对数据进行高效抽样 当数据量特别大时对全体数据进行处理存在困难时抽样就显得尤其重要了。抽样可以从被抽取的数据中估计和推断出整体的特性是科学实验、质量检验、社会调查普遍采用的一种经济有效的工作和研究方法。