Hive本身并不存储数据,而是将数据存储在Hadoop的HDFS中,表名对应HDFS中的目录/文件。根据数据的不同存储方式,将Hive表分为外部表、内部表、分区表和分桶表四种数据模型。每种数据模型各有优缺点。通过create user命令创建user表时,会在HDFS中生成一个user目录/文件。
外部表
数据不由Hive管理,使用drop命令删除一个表时,只是把表的元数据给删除了,而表的数据不会删除。 创建外部表的SQL语句:
create external table bigdata17_user(
userid int,
username string,
fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';
内部表
内部表(有些人会翻译成管理表)的数据由hive管理,当使用drop删除表时,会把表的元数据和数据一起删除,数据无法恢复,因此一定要慎用drop删除内部表。
创建内部表的sql语句:
create table bigdata17_user( userid int, username string, fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';
和外部表创建的语法基本一样,只是创建外部表需要使用external关键字。没有external关键字则是创建内部表。
分区表
内部表和外部表都可以使用分区的功能,使用分区的内部或外部表称为分区表。 创建分区表的语句:
create external table bigdata17_user_partition(
username string,
fullname string)
partitioned by(userid string)
row format delimited fields terminated by ','
lines terminated by '\n';
往分区表导入数据分为静态分区导入和动态分区导入,静态分区是在导入语句中指定分区值,例如:
insert overwrite table bigdata17-user_parttion
partition(userid=1)
select username ,fullname from bigdata17_user;
该语句的分区值默认是1,如果有多个分区值,必须写多个sql语句,效率低下。
一般情况在我们都是使用动态分区导入数据,
在导入数据之前必须执行下面的两条语句让hive支持动态分区功能,默认是不支持动态分区的。
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;
动态分区导入数据的sql语句:
insert overwrite table bigdata17_user_partition
partition(userid)
select username ,fullname,userid from bigdata17_user;
分桶表
分桶是将某个字段取哈希值,值相同的数据分发到一个桶中。在创建分桶表的时候必须指定分桶的字段,并且指定要分桶的数量。 创建分桶表对SQL语句如下:
create table bigdata17_user_bucket( userid int, username string, fullname string)
clustered by(userid) into 2 buckets
row format delimited fields terminated by ','
lines terminated by '\n';
注意:分区和分桶都是按字段来组织数据的存放,分区是相同的字段值存放在一个文件中,而分桶是字段哈希值相同的数据存放在一个文件中。