这次我们主要针对hive的操作表做简单的介绍:
- 托管表和外部表
- 分区和桶
这2个部分做简介
Hive表格逻辑上有存储的数据和描述表格中数据形式的相关元数据组成。数据一般存储在HDFS上,也可以存放在本地文件系统中。元数据存放在关系数据库中。
1. 托管表和外部表
托管表
- hive会把数据移动到它的仓库,这里使用的是load的命令,把文件系统的数据移动到hive的仓库目录,如果数据和表的结构不匹配,这里是不会异常,在查询的时候会出现null空值
//加载hdfs的数据,数据会移动到hive的表目录下
create table managed_table(dummy string);
load data inpath '/usr/tom/data.txt' into table manage_table;
//加载本地的数据,增加了local的关键字,数据不会移动
create table managed_table(dummy string);
load data local inpath '/usr/tom/data.txt' into table manage_table;
- 删除表 drop
drop table manage_table ;
会将表的元数据和表的数据一起删除,会导致数据彻底丢失。而load是移动操作,而drop是删除,所以这里是托管表.
外部表
create external table external_table(dummy string)
location '/usr/tom/external_table';
load data inpath '/usr/tom/data.txt' into table manage_table;
- 使用exterbnal关键字以后,hive知道数据不由自己管理,因此不会把数据移动到自己的目录。
- 在创建表的时候就声明了表的位置,在创建外部表的时候,不会检查外部文件是否存在,因此创建数据可以推迟到创建表之后,在创建表的时候只是对外部数据的引用,因此drop命令只会删除元数据的信息。
分区和桶
hive把表组织成partition(分区),这是根据一个分区列的值对表进行粗略的划分机制,使用分区还可以加快数据分片的查询速度。
表或者分区可以进一步分为桶,他会为数据提供额外的结构以获得更高效的查询。
分区
- 分区实际实在HDFS文件系统对应的表文件夹下面创建对应名称的文件夹,在我们通过分区查询的时候,直接制定到对应的文件所在目录,实现快速的查询。
- 一个表可以指定多个维度进行分区,他们回像树形目录结构一样展开,先创建的分区更靠近根目录。使用的关键字是 partitioned by
//创建表和分区
create table logs(ts string,line string)partitioned by (dt string,country string);
//加载数据,这里需要显式的指定分区的值
load data local inpath 'input/hive/partitions/file1' into table logs
partition (dt='2018-01-01',country='China');
//查询
select dt,ts,line form logs where country='China';
- 在查询的时候可以像执行正常的列那样指定分区,查询的时候会返回分区的值,但是实际只是读取了文件名,对应的数据文件并不存在。
分桶
把表组织成分桶有两个理由:
-
可以获得更高的查询处理效率,桶为表增加了额外的数据结构,在表结构中添加了几个列,连接在两个相同列上划分了桶的表,可以使用map端的连接高效的使用
-
在处理大规模数据的开发阶段,可以分桶后再对应的列上试运行查询。可以使取样更高效。
分桶使用的关键字使 clustered by 指定分桶所用的列和要划分桶的个数。
//创建分桶表
create table bucketed_users(id int,name string) clustered by (id) into 4 Buckets;
//创建分桶表,并按照id排序
create table bucketed_users(id int,name string) clustered by (id) sorted by (id ASC) into 4 Buckets;
//加载本地文件
load data local inpath 'input/hive/partitions/file1' into table bucketed_users;
这里会对值得哈希结果除以分桶个数取余,进行分配。
- 查询的时候,需要将***hive.enforce.bucketing属性设置为true***,使用下面的命令查询
//查询命令
insert overwrite table nba2 select * from nba2;
实际分桶的个数是和reduce任务的个数相同的,在执行查询的时候,实际执行的是MR程序。