Hive探秘--内部表、外部表、分区表、桶表研究

Hive知识

一、建表语法

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path]

二、 Hive的${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir属性指向的是Hive表数据存放的路径

三、内部表与外部表

内部表建表sql:

create table ext (
videoid String,
uploader String,
age int,
category array<String>,
length int,
views int,
rate float,
ratings int,
comments int,
relatedid array<String>
)
row format delimited fields terminated by "	"
collection items terminated by "&"
stored as textfile;

外部表建表sql:
create external table ext (
videoid String,
uploader String,
age int,
category array<String>,
length int,
views int,
rate float,
ratings int,
comments int,
relatedid array<String>
)
row format delimited fields terminated by "	"
collection items terminated by "&"
stored as textfile
location '/root/files';

建表语句区别:外部表有external关键字,需要制定location,其他都是相同的!
注意:location指定的是hdfs的位置,不是本地位置!
区别:删除表时,内部表会删除表的元数据和表数据;
外部表只删除表的元数据。

四、分区表

静态分区和动态分区的区别在于导入数据时,是手动输入分区名称,还是通过数据来判断数据分区,建表语句没有区别。
分区是表的部分列的集合,可以为频繁使用的数据建立分区,这样查找分区中的数据时就不需要扫描全表,这对于提高查找效率很有帮助。
在插入数据的时候指定分区,其实就是新建一个目录或者子目录,或者在原有的目录上添加数据文件。

创建分区表的SQL:
CREATE TABLE order_created_partition (
    orderNumber STRING
  , event_time  STRING)
PARTITIONED BY (event_month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '	';

分区列是数据的物理目录,也是select结果中正式的列。

Load data从外部文件或者insert overwrite into tb,静态分区指定分区列的值,源可以不包含该列的值或包含该列的值但被覆盖;动态分区分区列的值源数据中必须包含!

Hive分区是在创建表的时候用Partitioned by 关键字定义的,但要注意,Partitioned by子句中定义的列是表中正式的列,但是Hive下的数据文件中并不包含这些列,因为它们是目录名。

PARTITONED BY子句中定义的列是表中正式的列(分区列),但是数据文件内并不包含这些列。

分区是以字段的形式在表结构中存在,通过describe table命令可以查看到字段存在, 但是该字段不存放实际的数据内容,仅仅是分区的表示(伪列) 。 

静态分区有一个很大的问题,要求在partition关键字后面,对应分区列的值要被指定的。当分区列的值有很多个的时候,就需要重复执行很多次类似的insert语句。

         静态分区与动态分区的差别:静态分区一定会创建分区,不管select语句结果有没有数据,而洞天分区,只有select结果记录数大于0时才会创建分区。

         动态分区会为每一个分区分配reduce数,set mapred.reduce.tasks=100,会为每一个之分区分配100个recude,可能会压垮namenode。

开启动态分区:
set hive.exec.dynamic.partition=true;  
set hive.exec.dynamic.partition.mode=nonstrict;  
往动态分区里插入数据:

Insert overwrite table tb_name partition(par1, par2) select fields1,fields2…fieldn,par1,par2 from tab_name2 where …;

Overwrite表示覆盖原来的数据,也可以改成into,不管原来的数据。

注意:select数据的字段最后必须是动态分区字段!!!

静态分区:
Insert overwrite/into table tb_name partition(par1=’***’,par2=’***’) select fields1,field2…fieldsn… from tab_name2 where …

静态分区的select 字段中不能包含分区列

五、桶表

桶表是对数据进行哈希取值,然后放到不同文件中存储。

数据加载到桶表时,会对字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。
物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和reduce任务个数相同。

桶表专门用于抽样查询,是很专业性的,不是日常用来存储数据的表,需要抽样查询时,才创建和使用桶表。

 

大神讲的很好:http://blog.csdn.net/wisgood/article/details/17186107

http://blog.csdn.net/zengmingen/article/details/52620913

        

 

 

  

我要把所有的坑都趟平!
原文地址:https://www.cnblogs.com/loveling-0239/p/7388914.html