外部表与管理表
Create [EXTERNAL] table tablename(…)…
EXTERNAL关键字修饰的即表示为外部表,默认为管理表。
管理表与外部表的区别:
- 管理表使用drop删除表时会将数据删除,外部表不会删除数据,只会删除表结构。
- 管理表使用truncate删除数据时有效,外部表无效。
分区表
1.分区表的作用:
海量数据下避免全表扫描
分区实际上就是分文件夹,将分在同一区的的表的文件存在同一个文件夹下
分区的字段表现为文件夹,文件夹名便为该分区字段的值。
使用truncate清除表中的数据时,不会清除分区字段的信息(分区字段名用于创建按文件夹)。
建立分区表
Create table dept_partition(
Deptno int,
Dname string,
Loc string)
Partitioned by (month string)
Row format delimited fields terminated by ‘\t’;
说明:建立分区时需指定分区字段。
2. 向分区中导入数据(导入时指定分区)
Load data local inpath ‘/home/bduser/datas/dept’
into table dept_partition partition(month=’201901’);
Inser into table dept_partition partition(month=’201901’)
select * from dept;
3. 查询单一分区表中的数据(加入分区字段值即可,若不加且配置为严格模式会进行全表扫描)
Select * from dept_partition where month=’201901’;//和普通表的条件查询无区别。
4. 查询多个分区表中的数据(union)
Select * from dept_partition where month=’201901’
Union
Select * from dept_partition where month=’201902’;
5. 查询表有多少个分区
Show partitions dept_partition;
-
增加单个分区
Alter table dept_partition add partition(month=’201903’); -
增加多个分区
Alter table dept_partition add partition(month=’201904’) partition(month=’201905’);
//注意:添加分区实际一次添加一个分区(因为需要创建文件夹),与添加字段有所区别(字段一次可添加多个,因为只需修改文件内容)。 -
删除单个分区
Alter table dept_partition drop partition(month=’201905’); -
删除多个分区(注意分区之间加逗号)
Alter table dept_partition drop partition(month=‘201904’),parition(month=’201903’); -
关于二级分区
创建时指定分区如下即可:
Paritioned by(month=’201901’,day=’01’);
使用时类似。
查询时可以指定查询大分区的表内容:
Select * from dept_partition2 month=’201901’; -
对于已经在hdfs的hive仓库路径中创建了分区表形式的文件夹,传入数据后使之与新定义的表生效的方式:
方式一:msck修复,自动添加分区
创建文件夹:
hdfs dfs –mkdir /user/hive/warehouse/dept_partition/month=201902;
传文件:
hdfs dfs –put ./datas/dept.txt
查表:(查不出结果)
select * from dept_partition where month=’201902’//因为为创建month=201902分区,虽然手动创建了该文件夹,但是未将该文件夹和分区进行关联
msck修复:(修复过程中会自动添加该分区)
msck repair dept_partition;
说明:分区在创建过程发现hive仓库中已有分区文件夹,便直接关联该文件夹。
方式二:手动添加分区
Alter table dept_partition add partition(month=’201902’);
说明:分区在创建过程发现hive仓库中已有分区文件夹,便直接关联该文件夹。
方式三:load自接导入
创建文件夹:
hdfs dfs –mkdir /user/hive/warehouse/dept_partition/month=201902;
load导入:(注:此时还未创建分区)
load data local inpath ‘/home/bduser/datas/dept.txt’ into table
dept_partition partition(month=’201902’);
说明:load过程发现导入数据到未创建的分区,会自动创建该分区,此时存在创建文件夹的过程。
12.关于动态分区和静态分区
静态分区:是指导入数据时指定分区导入,如上文中提到的导入数据的方式。
动态分区:是指导入数据时不用指定具体分区,只需指定分区字段,hive根据字段进行自动分区。
说明:默认情况下hive支持动态分区,但是前提是必须至少有一个分区是通过静态方式导入。可通过修改配置使hive支持在没有静态分区的情况下也能动态导入。
Set hive.exec.dynamic.partition.mode=nonstrict;//开启非严格模式
动态分区实例:
create table dept_dymic(
dname string,
loc string)
partitioned by (deptno int)
row format delimited fields terminated by '\t';
导入数据:
Insert into dept_dymic partition(deptno) select dname,loc,deptno from dept;//导入的数据会自动进行分区
分桶表
- 为什么要分桶
使map端join更高效。
方便海量数据进行抽样查询。 - 分桶与分区的区别
本质实现不同:
分区的本质使分文件夹,将属于同于区的表数据存在同一个文件夹下
分桶的本质是分文件,将一个大文件分成多个按照某一特征均匀分布的多个文件。
注:分桶的实质就是对分桶的字段做了hash然后存放到对应文件中,所以说如果原有数据没有按key hash ,需要在插入分桶的时候hash, 也就是说向分桶表中插入数据的时候必然要执行一次MAPREDUCE,这也就是分桶表的数据基本只能通过从结果集查询插入的方式进行导入。 - 分桶表的创建
Create table dept_bucket(
Deptno int,
Dname string,
Loc string)
Clustered by(id) into 4 buckets;
Row format delimited terminated by ‘\t’; - 分桶表导入数据
① 配置属性值,使hive支持分桶:
Set hive.enforce.bucketing=true;//默认为false,表示不支持
Set mapreduce.job.reduces=-1;//也可以根据分桶的个数决定reduceTask开启的个数
② 导入数据
注:不能使用load直接导入到分桶表,因为导入数据显然需要经过mr计算各条数据分到那一个桶。
使用insert overwrite 导入数据
Insert into table dept_bucket select * from dept; - 分桶抽样查询
select * from dept_bucket tablesample(bucket 1 out of 4 on id);
注:tablesample 是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。
y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。
x表示从哪个bucket开始抽取。例如,table总bucket数为32,tablesample(bucket 3 out of 16),
表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。
- 数据块抽样
Hive 提供了另外一种按照百分比进行抽样的方式,这种是基于行数的,按照输入路径
下的数据块百分比进行的抽样。
hive (default)> select * from stu tablesample(0.1 percent) ;
提示:这种抽样方式不一定适用于所有的文件格式。另外,这种抽样的最小抽样单元是
一个 HDFS 数据块。因此,如果表的数据大小小于普通的块大小 128M 的话,那么将会
返回所有行