在建立普通表的时候,如果数据是有分区的,在ADD DATA的时候需要指明分区,比方下面的例子;
user表,包含 id bigint,name string,然后按照时间(date)来进行分区,路径存储在/user/*/test/下面,partition文件分别在
/user/*/test/dt=20140513
1^Amicheal
2^Abeckham
3^Adavid
和/user/*/test/dt=20130514
4^Ahello
5^Aworld
这个时候建表语句是这样:
DROP TABLE user_test;
CREATE TABLE user_test(
id bigint,
name string
)
PARTITIONED BY (dt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' 01'
LINES TERMINATED BY '
'
STORED AS TEXTFILE;
加入数据的时候写法如下:
LOAD DATA INPATH '/group/tbsc-dev/yuhan.zt/user/dt=20140514' INTO TABLE user_test partition (dt='20140514');
注意load data 操作dfs的数据时是mv操作,所以/group/tbsc-dev/yuhan.zt/user/dt=20140514目录下的数据就没有了。
查询一下select id,name from user_test
4 hello
5 world
--------------------------------------------------------------------------------------------------------
如果建立的是外部表
DROP TABLE user_test_external;
CREATE EXTERNAL TABLE user_test_external(
id bigint,
name string
)
PARTITIONED BY (dt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' 01'
LINES TERMINATED BY '
'
STORED AS TEXTFILE
LOCATION '/group/tbsc-dev/yuhan.zt/user';
这个时候如果你select * from user_test_external, 结果是空的。
原因是,你建立外部表的时候,外部表的相关信息与数据是存放在你的metastore里面的,虽然实际的数据地址 /group/tbsc-dev/yuhan.zt/user/ 是有分区的,
但是在metastore中外部表并不知道这一点,必须你要显示的说明一下,或者说告诉外部表一下;
ALTER TABLE user_test_external ADD PARTITION (dt=20140513)
然后在select id,name from user_test_external 就有值了
1 micheal
2 beckham
3 david
其实外部表的写法也可以在建表的时候不写明LOCATION,而在指明PARTITION的时候指明LOCATION
DROP TABLE user_test_external;
CREATE EXTERNAL TABLE user_test_external(
id bigint,
name string
)
PARTITIONED BY (dt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' 01'
LINES TERMINATED BY '
'
STORED AS TEXTFILE;
ALTER TABLE user_test_external ADD PARTITION (dt=20140513) LOCATION '/group/tbsc-dev/yuhan.zt/user/dt=20140513';