在hive中query外部表的简单测试

来源:互联网 发布:java开源报表框架 编辑:程序博客网 时间:2024/05/16 04:37

首先我们来了解一下Hive中两种不同的表。

Managed Tables
Managed tables or sometimes called internal tables, because Hive controls the lifecycle of their data (more or less). As we’ve seen, Hive stores the data for these tables in a subdirectory under the directory defined by hive.metastore.warehouse.dir (e.g., /user/hive/warehouse), by default. When we drop a managed table, Hive deletes the data in the table.  However, managed tables are less convenient for sharing with other tools. For example, suppose we have data that is created and used primarily by Pig or other tools, but we want to run some queries against it, but not give Hive ownership of the data. We can define an external table that points to that data, but doesn’t take ownership of it.

下面这个简单的语句就创建了一个内部表:

hive> create table x (a int);


External Tables

我们来看下面创建外部表的例子:

hive> CREATE EXTERNAL TABLE IF NOT EXISTS stocks (
exchange STRING,
symbol STRING,
ymd STRING,
price_open FLOAT,
price_high FLOAT,
price_low FLOAT,
price_close FLOAT,
volume INT,
price_adj_close FLOAT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/data/stocks';

对于hive来说,它对外部表的数据只有“使用权”,而不是owner。因为对于集群来说,数据可能被多个程序使用,例如hadoop,pig。因此有时hive不应该own这些数据。从上面的语句可见,在创建外部表的同时指定了数据所在的位置,而在创建managed table时并不需要指定数据。因此,对于内部表来说,如果想从中query数据,我们需要:

1,创建表的schema

2,导入数据到hive。

而对于外部表来说,仅需要创建表schema,就可以query数据了,不需要再导入数据。

需要注意的是,内部表也可以指定一个location参数,但是这个location是指让hive将数据存到何处,与创建外部表时的location作用不同。另外需要注意的是,如果hadoop工作在standalone模式下,location可以为本地目录。如果工作在伪分布式或分布式的模式下,location则需要是HDFS目录。需要注意的是,HDFS作为一个文件系统并不关心Block里存储的是什么,因此Block里的数据可以有不同的组织形式(file format)。最新版本的Hive支持以下file format:

txt, Avro, Parguet, RCFile, ORCFile, Sequence file, LZO-compressed txt

例如,下例创建一个内部表,该表指定使用RCFile 格式存储数据,同时使用lzo压缩算法。RCFile是一种行列混合存储格式,具体大家自行查资料。

-- PrepareCREATE TABLE rc_lzo (    client BIGINT, ctime INT, mtime INT,    code STRING, value_1 INT, value_2 INT) STORED AS RCFILE;-- CompressionSET hive.exec.compress.output=true;SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;-- ImportINSERT OVERWRITE TABLE rc_lzoSELECT * FROM (    SELECT        client, round(ctime / 1000), round(mtime / 1000),        code, value_1, value_2    FROM staging) T;


对于其它Hive默认不支持的file format,Hive提供了SerDe接口,用户可以自定义数据序列化和反序列化程序。Hive会自动调用用户自定义的程序,从而使用这些数据。

使用不同的file format,可以使用不同的压缩算法,从而提高存储效率。另外如果应用程序本身使用的,或数据来源就是某种特殊数据,那么当数据进入Hive时就不需要转换,可以直接使用。


测试过程

开始前需要确认hadoop和hive都已经安装好了。我们可以在hive shell中执行show tables;来检查hive是否可以正常工作。

1,首先准备一个csv文件用于测试。将这个csv文件放到linux的某个目录下。

2,如果hadoop工作在standalone模式下,则可以跳过这步直接创建table。如果工作在伪分布式或分布式模式下,则需要将csv拷贝都hdfs中才能使用。

$ hadoop fs -put /home/DBA/TestData/*.csv /user/hadoop/input  -- input是hadoop的默认input目录,我们也可以使用别的目录,只要是hdfs的就行。

$ hadoop fs -ls /user/hadoop/input -- 检验文件已经准备好。

3,创建table

CREATE EXTERNAL TABLE IF NOT EXISTS backupStatus1 (
ServerName STRING,
DatabaseName STRING,
LastBackedUpDate TIMESTAMP,
LastBackupStatus STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/hadoop/input';

4,然后就可以query了。

select * from backupStatus1 where servername like 'SomeBox'; 上面这两步都是在HIVE shell中执行命令。