外部表与partition

时间:2023-03-09 07:20:38
外部表与partition

在建立普通表的时候,如果数据是有分区的,在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 '\001'
LINES TERMINATED BY '\n'
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 '\001'
LINES TERMINATED BY '\n'
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 '\001'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

ALTER TABLE user_test_external ADD PARTITION (dt=20140513) LOCATION '/group/tbsc-dev/yuhan.zt/user/dt=20140513';