hive-1 受控表简介(分区表 桶表)

 

 

1 受控表(managed table):

 

hive中将创建的表和实际对应hdfs目录结构和文件相对应,如果删除hive中创建的表,对应hdfs的目录和文件

将不复存在,这种表叫做受控表。

 

受控表(managed table)包括内部表、分区表、桶表。

 

 

2 分区表简介:

 

a) 分区表是把数据放在不同的磁盘文件中,hive数据库会对不同分区进行单独管理,优化,

     最终会加快数据查询速度。
b) 分区表分区的含义:也是把数据进行划分不同的区,hive中的区是指不同子文件夹中。

c) 分区表创建原因: 100M的学生信息,如果查询班级为1班的学生,在不使用分区表时,
     需要去100M中遍历查询,如果使用分区表,只需要去文件夹名称为1班的hdfs文件中查找即可。

d) 分区字段简介:

     d.1) 分区字段就是文件夹的标识名称,

     d.2) 在正常使用的时候,分区字段是作为正常字段被使用,但是在数据文件中不存在,

            仅作为虚拟列(virtual column)存在

 

e)  分区过多的坏处:
     如果分区过多,hive在扫描时,一级级的扫来扫去,会增加扫描成本, 在运行时,对于map端造成map任务增多。

 

f) 选用哪些字段作为分区呢:
   f.1) 选用平时查询比较频繁的字段,比如 地区 时间查,
   f.2) 分区后产生的文件并不是很多的字段来, 比如 按照姓名 ID来查询,就不能使用分区,否则要产生很多分区

 

g)  操作:

   g.1) 单分区表创建和查询:

创建单分区表:
create table jiuye(id int, name string) partitioned by(grade int) row format delimited fields terminated by '\t';
load data local inpath '/usr/local/data/user' into table jiuye partition(grade='1');
load data local inpath '/usr/local/data/user' into table jiuye partition(grade='2');
load data local inpath '/usr/local/data/user' into table jiuye partition(grade='3');

从单分区表中查询数据
select * from jiuye where grade=3 // 此语句仅仅会从文件夹名称为3的hdfs中查找数据

注意 这个分区字段 '' 也可以不加,比如写成:
load data local inpath '/usr/local/data/user' into table jiuye partition(grade=3);

查询结果:
hive> select * from jiuye where grade = 3
    > ;
OK
1       zhangsan        3
2       lisi    3
3       wangwu  3
4       zhaoliu 3

 

分区后hdfs的样子:


hive-1 受控表简介(分区表 桶表)_第1张图片
 

 g.2) 多分区字段插入和查询写法:

create table member(id int, name string) partitioned by(year int, month int) row format delimited fields terminated by '\t';
load data local inpath '/usr/local/data/user' into table member partition(year=2014, month=1);// hdfs中目录为  2014/1/member
load data local inpath '/usr/local/data/user' into table member partition(year=2014, month=2);// hdfs中目录为  2014/2/member



hive> select * from member where year=2014 and month=1;
OK
1       zhangsan        2014    1
2       lisi    2014    1
3       wangwu  2014    1
4       zhaoliu 2014    1

 

  g.3) 缺陷:

选定分区字段之后, 结果会造成数据偏差特别大,这样整个查询时间受制于分区特别大的,对于整个作业的运行效率是不好的,
比如 淘宝按照用户所在省份来分区, 北京的订单用户要比青海西藏等偏远省的总和还要多很多

 

3 桶表简介:

 

a) 概念: 桶表是对数据进行哈希取值,然后放到不同文件中存储,数据加载到桶表时,会对某字段(这个字段会在创建桶表时通过clustered by(xx)指定)取hash值,然后与桶的数量取模。把数据放到对应的文件中,

Hive会启动一个MapReducejob来产生数据,该jobreduce任务的数量与桶的数量是一致的。每个reduce任务会产生一个文件

<!--EndFragment-->

b) 使用场景:

适用于: 抽样查询  或者表连接查询
不适用于: 根据业务查询数据(因为数据是按照hash来存放,和业务没有任何关系)

c) 和分区表的异同:

相同点: 都是用于对数据的划分
不同点: 前者是根据业务来进行划分,后者是抛弃业务字段从纯数据角度来划分

d) 操作写法:

创建表
	create table buck(id int, name string) clustered by(id) into 4 buckets; 分成4个桶,使用id和4取模,根据结果不同分到不同文件中存储	
加载数据
	set hive.enforce.bucketing = true; // 启用桶 (默认是不用桶的)	
	insert overwrite table bucket_table select name from stu;  //  会对id进行hash计算然后在将数据放在不同桶中, 分区表中加载数据仅仅是将磁盘数据直接加载到hive中

 结果:

stu数据:
1       zhangsan
2       lisi
3       wangwu
4       zhaoliu
1       zhangsan
2       lisi
3       wangwu
4       zhaoliu
1       zhangsan
2       lisi
3       wangwu
4       zhaoliu

 

   


hive-1 受控表简介(分区表 桶表)_第2张图片
 


hive-1 受控表简介(分区表 桶表)_第3张图片
 

其余三个文件内容在此不再展示 ....

 

 

 

4 外部表简介:

 

只需要指定目录即可, 比较灵活,

外部表   

create external table ext_table(c1 string, c2 string) row format delimited fields terminated by '\t' location '/files';

1 使用关键词 external表面外部表。 '/files' 表示关联 hdfs文件系统根目录下files目录内将文件 hello hello1内的数据
2 location用于指定数据在哪里,只能使用文件夹来指定位置,
3 删除外部表 不会损坏hdfs文件内容

 


创建后数据为:

hive> select * from ext_table;
OK
1,zhangsan      NULL
2,lisi  NULL
3,wangwu        NULL
1,45    NULL
2,56    NULL
3,89    NULL

 


删除后 hdfs/files内文件 hello hell1均存在:

 

你可能感兴趣的:(hive)