一、 有关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 命令之前数据如下所示:
执行load 命令之后:
- 2、查询外部表内容
- 3、查询外部表中的文件路径
select INPUT__FILE__NAME from t_external;
- 4、如果删除外部表,只会将其对应的元数据删除了,目录中的数据并不会被删除
hive> drop table t_external;
hive> select * from t_external;
FAILED: SemanticException [Error 10001]: Line 1:14 Table not found 't_external'
由上可见对应的数据并没有被删除。
- 综上所述:外部表与内部表的区别如下
- 1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而表则不一样;
- 2、在删除表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!
那么,应该如何选择使用哪种表呢?在大多数情况没有太多的区别,因此选择只是个人喜好的问题。但是作为一个经验,如果所有处理都需要由Hive完成,那么你应该创建表,否则使用外部表!
hadoop权威指南3如下建议
四、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
由上述可知加载数据到分区后数据的目录可能如下所述:
- 综上所述,分区只不过是将表中指定的文件存储到更细化的文件目录中,比如以时间为分区,那么每天的数据则会存储到以日期为目录的路径下,当进行查询时在sql中指定where那个分区时就不用进行全表查询,而是只需要查询某一天这个目录下的数据,很明显这么做大大地加快了查询的速度。