一. Partition

在Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了partition概念
分区表指的是在创建表时指定的partition的分区空间
如果需要创建有分区的表,需要在create表的时候调用可选参数partitioned by,详见表创建的语法结构

一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。
分区是以字段的形式在表结构中存在,通过describe table命令可以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示
语法例子:

PARTITIONED BY (`dt` string COMMENT '日期分区')

分区建表分为2种,一种是单分区,也就是说在表文件夹目录下只有一级文件夹目录。另外一种是多分区,表文件夹下出现多文件夹嵌套模式
单分区建表语句:

-- 单分区表,按天分区,在表结构中存在id,content,dt三列。
create table day_table (id int, content string) partitioned by (dt string);

双分区建表语句:

-- 双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。
create table day_hour_table (id int, content string) partitioned by (dt string, hour string);

添加分区(表已经创建,再添加):

alter table 表名 add if not exists partition(dt='$DATE');

删除分区

-- 元数据和数据将被一并删除
alter table 表名 drop if exists partition(dt='$DATE');

数据加载进分区

-- 语法
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
-- local后指定的路径是本地,文件复制;不带lcoal的路径是分布式系统,文件转移;
-- 装载进去,数据不会转换
LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08- 08', hour='08'); 
LOAD DATA local INPATH '/user/hua/*' INTO TABLE day_hour partition(dt='2010-07- 07');

查看分区

show partitions day_hour_table;

在Hive中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在最字集的目录中
总的说来partition就是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理

二. 内部表和外部表

Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。
在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
传统数据库对表数据验证是schema on writ(写时模式),而Hive在load时是不检查数据是否符合schema的,hive 遵循的是schema on read(读时模式),只有在读的时候hive才检查、解析具体的
数据字段、schema。
读时模式的优势是load data 非常迅速,因为它不需要读取数据进行解析,仅仅进行文件的复制或者移动。 写时模式的优势是提升了查询性能,因为预先解析之后可以对列建立索引,并压缩,但这样也会花费要多的加载时间。

内部表
建立内部表

create table tt (name string , age string) location '/input/table_data';

会在hdfs上新建一个tt表的数据存放地,: hdfs://master/input/table_data
导入数据

load data inpath '/input/data' into table tt;

此时会将hdfs上的/input/data目录下的数据转移到/input/table_data目录下
删除tt表后,会将tt表的数据和元数据信息全部删除,即最后/input/table_data下无数据,当然/input/data下在上一步load data操作后已经没有了数据!
注意的地方就是:load data会转移数据!

外部表

create external table et (name string , age string);

此时,会在hdfs的/user/hive/warehouse/下面新建一个表目录et

load data inpath '/input/edata' into table et;

此时会把hdfs上/input/edata/下的数据转到/user/hive/warehouse/et下,删除这个外部表后,/user/hive/warehouse/et下的数据不会删除,但是/input/edata/下的数据在上一步load后已经没有了!数据的位置发生了变化!本质是load一个hdfs上的数据时会转移数据!
其他

  • 加上location用法一样,只不过表目录的位置不同而已。
  • 加上partition用法也一样,只不过表目录下会有分区目录而已。
  • load data local inpath直接把本地文件系统的数据上传到hdfs上,有location上传到location指定的位置上,没有的话上传到hive默认配置的数据仓库中。

总结:
表的元数据存在mysql中
如果指定location,数据存放的位置就是location,如果未指定,默认使用配置的路径/user/hive/warehouse
外部表只是不删除数据,外部表是为了在创建的时候,把指定路径下的内容囊括进来