1,现象演示:
创建数据库:
create database if not exists ma_ex
comment 'manager_external'
with dbproperties ('name'='dachun','date'='20200202');
我的另一篇博客详细介绍了Hive的数据库操作
2,内部表演示
创建内部表(MANAGED _TABLE):创建内部表也可以指定location,内部表的数据文件就会存储在指定路径下,否则走默认的当前库/表名
create table if not exists one(
id int,
name string
) row format delimited fields termited by ',';
内部表insert方式插入数据,生产千万不要用
因为他是每插入一条数据,就会在该表目录下生成一个小文件,每一个小文件对应一条数据,10W条对应10W个小文件
insert into one values(1,'dema');
insert into one values(2,'xiya');
内部表load方式插入数据
load data local inpath '/home/hadoopadmin/one.txt' into table one
load方式直接把这个文件拷贝到了目录下.
或者不用这个load命令,直接再拷贝一个文件到表one目录下,执行select* from one发现数据也加载进来了
hdfs dfs -put /home/hadoopadmin/one.txt
/user/hive/warehouse/ma_ex.db/one/one2.txt
在MySQL的元数据表TBLS里面查看
select * from TBLS;
字段TBL_TYPE=MANAGED_TABLE表示是内部表
3,外部表不带location演示
创建外部表
create external table if not exists one_external(
id int,
name string
) row format delimited fields terminated by ',';
如果创建外部表时候末尾没有加上location,
他默认读取的是自己database/自己tablename/文件
通过hdfs上传文件方式往这个目录下上传一个文件
hdfs dfs -put /home/hadoopadmin/one.txt /user/hive/warehouse/ma_ex.db/one_external
通过load方式网这个表里面添加数据
load data local inpath '/home/hadoopadmin/one2.txt' into table one_external;
外部表同样也可以通过insert方式添加数据,同样对应目录下新增一个文件
insert into one_external values(1,'lala');
上面三中添加方式都可以在外部表添加数据
查看元数据TABLS
4,外部表带location演示
创建外部表时候指定新的location
首先将文件导入到外部表的目录下
hdfs dfs -put /home/hadoopadmin/one.txt /user/hive/warehouse/external/
create external table if not exists one_external2(
id int,
name string
) row format delimited fields terminated by ','
location '/user/hive/warehouse/external/'
因为我们在外部表的路径下已经导入了文件
直接执行select * from one_external2是能够看到数据的
hive (ma_ex)> select * from one_external2;
OK
3 shuruima
4 heisemeigui
5 niuqu
在元数据存储的表的表TBLS也能看到
但是在hdfs上面并不能能够看到相关的目录,在该表数据库文件夹的下关于external2的目录也无法找到,通过下面这个desc formatted 表名,能够知道这个外部表的路径定在了外部表建表语句的location的文件夹下
为什么可以确认外部表的文件夹自动定位到了location文件夹下呢?
1,通过下面的desc table formatted确定了
2,insert into 表 values ();执行完之后,发现这个外部表的location文件夹下多出来一个文件,这个文件就是我们插入的这一条数据,所以呢,这就定位到了,创建带location的外部表对应的表数据存储路径就默认使用这个location位置
5,desc formatted 表名获取信息
使用desc formatted 表名,截图关键点
desc formatted one;
desc formatted one_external;
desc formatted one_external2;
我们会发现指定location的外部表,这个location路径就是它对应的文件的路径,他并没有自己创建相关路径,但是创建内部表和没有指定路径的外部表他是在数据库的hdfs路径下真实创建了这个文件夹.下面以删除表为例测试.
6,总结
总结:内部表
内部表创建时候,会在hdfs文件系统上面创建相应的路径文件夹,相关表的数据都会存在里面,如果是insert into 进去的数据,每一条都会对应一个小文件,可以把文件已load方式加载进去或者直接把文件放到hdfs文件系统对应的路径里面,前提是创建表的时候,制定好分隔符,然后执行select * from 表,就可以将文件里面的数据读到表中
删除内部表(MANAGED_TABLE)的时候,在 MySQL的元数据表TBLS里面对应的one表内容被删除,另外HDFS文件系统上面的该表的数据都会被删除
总结:外部表没有指定location.
外部表没有指定location版本创建时候,会在hdfs文件系统上面创建相应的路径文件夹,相关表的数据都会存在里面,如果是insert into 进去的数据,每一条都会对应一个小文件,可以把文件已load方式加载进去或者直接把文件放到hdfs文件系统对应的路径里面,前提是创建表的时候,制定好分隔符,然后执行select * from 表,就可以将文件里面的数据读到表中
删除时候,对应的hdfs上面的表路径以及数据都不会删除,即使没指定location,自己创建路径的话,还是没有删除.但是在 MySQL的元数据表TBLS里面对应的表内容被删除.
总结:外部表指定location.
创建时候,如果指定了location的话,该外部表对应的存储路径文件夹=location指定的文件夹位置,通过desc formatted tablename和insert into方式插入一条数据会多一个文件在location文件夹下,得到了验证
删除时候,对应的hdfs上面的表路径以及数据都不会删除,即使没指定location,自己创建路径的话,还是没有删除.但是在 MySQL的元数据表TBLS里面对应的表内容被删除.
7,内部表和外部表和外部表-location三者异同点
内部表和外部表的共同点:
指定好了分隔符的情况下,直接往他们相关的目录下不管是load文件,还是直接hdfs命令上传文件到这个路径,都可以被识别为表数据,而且都会在MySQL元数据TBLS表里面存储,删除表的时候对应的TBLS元数据都被删除
另外在hdfs文件系统的a数据库文件夹下都有一个one的文件夹,如果a数据库下创建一个内部表one,或者创建一个外部表one指定location为one这个路径,或者创建外部表one不带location,他们三个读出来的数据一样.
内部表和外部表不同点:
内部表会把hdfs表相关的文件文件夹全干掉,外部表就不会
外部表指定location和没指定location异同点:
指定location的话该表的数据都存储在location下,没指定location的话,数据都存储在当前数据库文件夹下一个名字为该表名的文件夹下,删除表时候hdfs上面数据都不会被删除,但是MySQL的元数据库表TBLS数据都会被删除.
Hive官方介绍
https://cwiki.apache.org/confluence/display/Hive/Managed+vs.+External+Tables