洗引擎数据的时候,由于改动了几个字段,因此需要删除原来关联了HDFS指定路径的外部表,重新建外部表表并关联HDFS。问题就出现在删外部表上,开始使用truncate的时候,发现并不能 删除外部表,于是查了查发现truncate只能删除内部表,于是果断使用一下命令将外部表先变成了内部表,然后再使用drop进行删除
alter table xxx set tblproperties('external'='false')
drop table xxx
结果表是给删除了,然后发现HDFS上关联路径下的分区数据也全部没了,然后就开始了凄惨的补数据之路...
现在总结下外部表和内部表:
1.内、外部表区别与联系
外部表——>创建表的时候指定external,外部表在删除之后,仅会删除hive外部表中元数据,不会删除数据和指定路径
内部表——>删除内部表会将数据和默认路径都删除,因此可能会误删数据,谨慎操作
教训:千万不要为了删除外部表就将外部表先转化为内部表,这样会将HDFS上的数据一并删除的
内外部表转换
内部表——>外部表:alter table xxx set tblproperties('external'='false')
外部表——>内部表:alter table xxx set tblproperties('external'='true')
2.truncate和drop以及delete简介
1)truncate:用于删除表或者分区中所有的行,但表结构及其列、约束、索引等保持不变,而且不记录单个行删除操作
-
truncate table tablename [partition partition_spec] 省略了partition会删除表中所有分区
-
truncate不能用于删除外部表,因为外部表中只是存放着元数据,真实数据并不在hive中
2)delete: 可以删除特定行,也可以删除所有行,并且在事务日志中为所删除的每行记录一项
-
不带where字句的delete和truncate功能相同,均是删除表中的全部行,但是truncate速度快,并且使用的系统和事务日志资源少
-
由foreign key约束引用的表,不能使用truncate删除,而应该使用不带where子句的delete进行删除,由于truncate table不记录在日志中,所以它不能激活触发器
3)drop:删除整个表数据及其表定义
- drop table [if exists] tablename
3.删除外部表——这样可以避免误删关联路径中数据
1)删除外部表分区
alter table tablename drop partition(partitions...)
2)删除HDFS上的数据
hdfs dfs -ls url_name
reference: