一、 有关Hive的一些小结:

  • Hive 是一个建立在hadoop文件系统上的数据仓库架构,可以用其对hdfs上数据进行分析与管理。
  • 实际上是将hdfs上的文件映射成table(按文件格式创建table,然后hive的数据仓库会生成对应的目录,默认的仓库路径:user/hive/warehouse/tablename,目录名与这个表名相同,这时只要将符合table定义的文件加载到该目录便可通过Hql对整个目录的文件进行查询了。
  • 将数据加载到该目录可以用hdfs dfs -put 命令直接添加到该目录;
  • 也可以通过load data local inpath ‘user/test.txt’ into table tableName,通过load命令加载数据与通过put命令加载文件的结果是一样的,即在user/hive/warehouse/tablename 目录下都会有加载进来的文件,如果用load命令加载的是hdfs上的文件则会将原hdfs目录下对应的文件移动至hive的仓库目录下),并将这些元数据保存到关系型数据库中,元数据存储着表所对应的文件路径,表的列与分区,表创建时间,文件大小等属性;
  • 同时支持用户运用类sql对文件进行操作,这个操作主要是查询。

hive 的数据模型中四种表:

-Table内部表 
 -External Table 外部表
 -Partition分区表 
 -Bucket Table 桶表

二、内部表

  • 表:Hive中的表和关系型数据库中的表在概念上很类似,每个表在HDFS中都有相应的目录用来存储表的数据,这个目录可以通过${HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.warehouse.dir属性来配置,这个属性默认的值是/user/hive/warehouse(这个目录在HDFS上),我们可以根据实际的情况来修改这个配置。
  • 如果我有一个表test,那么在HDFS中会创建/user/hive/warehouse/test目录(这里假定hive.metastore.warehouse.dir配置为/user/hive/warehouse);test表所对应的所有数据都存放在这个目录中。
  • 如果删除这张表,则表在关系数据中存储的元数据以及在warehouse目录下的数据也会被清除掉。

三、External Table 外部表

  • Hive中的外部表和表很类似,但是其数据不是放在自己表所属的目录中,而是存放到别处,这样的好处是如果你要删除这个外部表,该外部表所指向的数据是不会被删除的,它只会删除外部表对应的元数据;而如果你要删除内部表,该表对应的所有数据包括元数据都会被删除。
    外部表操作演示:
  • 1、创建外部表(创建的时候得用LOCATION 指定原数据存储的路径,不指定的话hive会在user/hive/warehouse下以外部表的表名创建目录并将数据存储在这里)
create EXTERNAL table t_external (year string,month int,num int)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ','
LOCATION '/usr/extends';
  • 加载数据可用:hdfs dfs -put filename /usr/extends
    也可用: hive>load data local inpath ‘/home/centosm/test/hive’ into table t_external;
    执行load 命令之前数据如下所示:

hive 创建表 指定为ORC格式 hive create external table_hadoop

hive 创建表 指定为ORC格式 hive create external table_数据仓库_02

执行load 命令之后:

hive 创建表 指定为ORC格式 hive create external table_hive 创建表 指定为ORC格式_03

  • 2、查询外部表内容

hive 创建表 指定为ORC格式 hive create external table_hive_04

  • 3、查询外部表中的文件路径
    select INPUT__FILE__NAME from t_external;

hive 创建表 指定为ORC格式 hive create external table_数据_05

  • 4、如果删除外部表,只会将其对应的元数据删除了,目录中的数据并不会被删除
hive> drop table t_external;
hive> select * from t_external;
FAILED: SemanticException [Error 10001]: Line 1:14 Table not found 't_external'

hive 创建表 指定为ORC格式 hive create external table_hadoop_06

由上可见对应的数据并没有被删除。

  • 综上所述:外部表与内部表的区别如下
  • 1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而表则不一样;
  • 2、在删除表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!
    那么,应该如何选择使用哪种表呢?在大多数情况没有太多的区别,因此选择只是个人喜好的问题。但是作为一个经验,如果所有处理都需要由Hive完成,那么你应该创建表,否则使用外部表!

hadoop权威指南3如下建议

hive 创建表 指定为ORC格式 hive create external table_hive_07

四、Partition分区表

  • 在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。

下面以实际操作来明显的展示分区:
创建分区表:

create table t_partition(ts bigint,line string)  
partitioned by (dt string,country string)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',';

查看表结构:

hive> desc t_partition;
OK
ts                      bigint                                      
line                    string                                      
dt                      string                                      
country                 string                                      

 # Partition Information          
 # col_name              data_type               comment             

dt                              string                                      
country                     string

向表中导入数据:

load data local inpath '/home/centosm/test/file3.txt'
into table t_partition
partition(dt='2017-04-01',country='US');

。。。。导入多个文件到不同分区

数据导完后查询表中数据如下:

hive> select * from t_partition;
OK
1111111         hello file1     2017-03-01      GB
2222            hello file2     2017-03-01      GB
123122222222    helloFile3      2017-04-01      CH
123122222222    helloFile3      2017-04-01      US
Time taken: 0.158 seconds, Fetched: 4 row(s)

hive> select * from t_partition where country='US';
OK
123122222222    helloFile3      2017-04-01      US

hive>  select * from t_partition where country='US' and dt='2017-04-01' ;
OK
123122222222    helloFile3      2017-04-01      US
Time taken: 0.216 seconds, Fetched: 1 row(s)

hive>  select * from t_partition where country='US' or dt='2017-03-01' ;
OK
1111111 hello file1     2017-03-01      GB
2222    hello file2     2017-03-01      GB
123122222222    helloFile3      2017-04-01      US
Time taken: 0.13 seconds, Fetched: 3 row(s)

查询表分区

hive> show partitions t_partition;
OK
dt=2017-03-01/country=GB
dt=2017-04-01/country=CH
dt=2017-04-01/country=US
Time taken: 0.074 seconds, Fetched: 3 row(s)

查询hive存储数据的目录如下

hadoop fs -ls /user/hive/warehouse/t_partition/dt=2017-03-01/country=GB
Found 2 items
-rwxr-xr-x   1 centosm supergroup         20 2017-03-25 01:11 /user/hive/warehouse/t_partition/dt=2017-03-01/country=GB/file.txt
-rwxr-xr-x   1 centosm supergroup         17 2017-03-25 01:14 /user/hive/warehouse/t_partition/dt=2017-03-01/country=GB/file2.txt

由上述可知加载数据到分区后数据的目录可能如下所述:

hive 创建表 指定为ORC格式 hive create external table_hive 创建表 指定为ORC格式_08

  • 综上所述,分区只不过是将表中指定的文件存储到更细化的文件目录中,比如以时间为分区,那么每天的数据则会存储到以日期为目录的路径下,当进行查询时在sql中指定where那个分区时就不用进行全表查询,而是只需要查询某一天这个目录下的数据,很明显这么做大大地加快了查询的速度。