hive的数据存储(元数据,表数据)和内部表,外部表,分区表的创建和区别作用

本文详细介绍了Hive中的各种表类型,包括内部表、外部表和分区表的特点及应用场景,并探讨了桶表的概念及其在数据处理中的优势。

hive的数据存储:

首先弄清楚什么是元数据和表数据:元数据就是表的属性数据,表的名字,列信息,分区等标的属性信息,它是存放在RMDBS传统数据库中的(如,mysql)。表数据就是表中成千上万条数据了。

hive的存储过程:启动hive时,会初始化hive,这时会在mysql中生成大约36张表(后续随着业务的复杂会增加),然后创建表,会在mysql中存放这个表的信息(不是以表的形式存在的,而是把表的属性以数据的形式放在mysql中,这样在hive中使用sql命令一样是能够查到这张表的)。然后把本地的文本文件使用hive命令格式化导入到表中,这样这些数据就存放到hdfs中,而不是在mysql或hive中。

内部表,

 hive> create table student(id int, name string, sex string, age int, department string) row format delimited fields terminated by ",";

我创建了一个studetn表,在mysql中是看不到这个表的:


而是使用命令,查找上面的tbls这个表:

mysql> select * from hive.TBLS;


然后在导入数据(hive不能进行增删改,也就是不能使用insert into ,update,delete等命令;想一想我们做大数据统计是分析数据的,而不是修改数据,再者数据是以文本的形式放在hdfs中的,因此不能修改数据):我这里上传本地txt文件

hive> load data local inpath "/home/xiaoye/students.txt" into table student;
Copying data from file:/home/xiaoye/students.txt
Copying file: file:/home/xiaoye/students.txt
Loading data to table hive2.student
Table hive2.student stats: [numFiles=1, numRows=0, totalSize=56, rawDataSize=0]
OK
Time taken: 6.346 seconds
hive> select * from student;
OK
1       小明    man     12      NULL
2       小红    woman   14      NULL
3       xiaoliang       man     13      NULL
Time taken: 0.964 seconds, Fetched: 3 row(s)
hive> desc student;
OK
id                      int                                         
name                    string                                      
sex                     string                                      
age                     int                                         
department              string                                

再到hdfs页面上有没有生成对应的数据:


说明没问题。

---------------------------------------------------------------------------------------------------------

外部表案例(这里就使用网友大神的博文,更美观):


0: jdbc:hive2://hadoop3:10000> create external table student_ext
(id int, name string, sex string, age int,department string) row format delimited fields terminated by "," location "/hive/student";
No rows affected (0.248 seconds)

--------------------------------------------------------------------------------------------------------------------------------

内部表外部表区别:

首先二者不是共存关系也不是修改关系,而是一开始创建表的使用要想好你到底需要什么样的表。

然后,  1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下(如果指定了location的话),也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样;

     2、在删除内部表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!

 3. 在创建内部表或外部表时加上location 的效果是一样的,只不过表目录的位置不同而已,加上partition用法也一样,只不过表目录下会有分区目录而已,load data local inpath直接把本地文件系统的数据上传到hdfs上,有location上传到location指定的位置上,没有的话上传到hive默认配置的数据仓库中。

外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。 

那么,应该如何选择使用哪种表呢?在大多数情况没有太多的区别,因此选择只是个人喜好的问题。但是作为一个经验,如果所有处理都需要由Hive完成,那么你应该创建表,否则使用外部表!


-----------------------------------------------------------------------------------------------------

分区表:

0: jdbc:hive2://hadoop3:10000> create external table student_ptn(id int, name string, sex string, age int,department string)
. . . . . . . . . . . . . . .> partitioned by (city string)
. . . . . . . . . . . . . . .> row format delimited fields terminated by ","
. . . . . . . . . . . . . . .> location "/hive/student_ptn";
No rows affected (0.24 seconds)

添加分区

0: jdbc:hive2://hadoop3:10000> alter table student_ptn add partition(city="beijing");
No rows affected (0.269 seconds)
0: jdbc:hive2://hadoop3:10000> alter table student_ptn add partition(city="shenzhen");
No rows affected (0.236 seconds)
0: jdbc:hive2://hadoop3:10000> 

为什么要使用分区表呢?

看上面的例子很显然,这是个学生表,然后以城市分区,这样就能够根据学生所在市不同把不同的分区分在表中不同的子文件夹中.这样数据也就在不同的磁盘文件中,数据库对不同的分区会进行单独的管理,优化,最终的目的是加快我们数据查询的速度。

--------------------------------------------------------------------------------------------------------------------------------

最后还有个桶,这个有点难理解,就不做多说了就放个案例吧:

0: jdbc:hive2://hadoop3:10000> create external table student_bck(id int, name string, sex string, age int,department string)
. . . . . . . . . . . . . . .> clustered by (id) sorted by (id asc, name desc) into 4 buckets
. . . . . . . . . . . . . . .> row format delimited fields terminated by ","
. . . . . . . . . . . . . . .> location "/hive/student_bck";

---------------------------------------------

增加 桶:

桶表(bucket table):

  原理:

    分区表是按照经常查询的字段做不同的分区,查询时就可以按分区进行查了.这样可以减小全局扫描提高查询的速度.分区表的缺陷就是选定了分区字段之后,结果会造成数据偏差特别大,有的分区数据特别大,有的分区数据特别小,这个时候作业的整个查询时间就受制于分区中数据特别大的那个分区,对整个作业的运行效率是不好的.
    桶表和分区表的区别在于:不是按照业务字段来进行分区,对里面的记录做一个hash,记录做完hash之后就没有规律了,可以简单的认为数据做完hash之后都不相同,然后我们让数据进行模10,数据就被分成了十份,模100就被分成100份,因为hash值几乎各不相同,所以模后的结果,分成10份或者100份,每一份的数据量几乎是一样多的,当你hash之后然后模一个数字,分的那些数据量,每一份应该是差不多的,如果这样的话,我们把这样的数据存起来,模5,10,100 模的这个数字叫做桶,模几就分成几个桶,桶实际上就是模的数字,我们的记录就被划分到这个桶里面了,那么hive在进行查询的时候就会按照5个桶或者10个桶来进行处理,这样的话,好处是各个map运行的时间差不多.
  桶表用的领域很少,一般用在表连接中,有两个表,有一个外键是连接字段,我们的这一个表里面的字段和另外一个的连接字段的值是相同的,hash后的值应该也相同,分桶的话会分到相同的桶中,在进行表连接的时候就比较方便了,只需要把对应的桶的数据连接一下然后再从里边查数据就方便了.

  还有一个优点就是在进行抽样查询的时候,我们的记录只有10亿条记录,要查一下北京的有多少个,没必要把十亿条记录全扫一遍,但是可以扫一万或者一百万看一下北京的有多少,然后就可以大体的判断一下北京的大约占多少百分比了.抽样不需要一个准确的值,只需要一个样本就可以了,这样样本只要符合统计学上的大小就可以了,那么我们在进行抽样的话,如果按照桶表来进行抽样更合理,如果按时间抽,统计结果就不准了.

  创建桶表:

    create table bucket_table(id int,name string) clustered by(id) into 3 buckets;

  加载数据:

    需要计算id的hash值,分桶.所以不能使用load data,load data加载方式是直接把数据从我们的磁盘复制到hdfs目录下,但是我们的分桶需要计算,计算需要走mapreduce,所以需要通过这种方式走mapreduce

    设置启用桶 set hive.enforce.bucketing=true;
  insert overwrite table bucket_table select id,name from jiuye;

  分桶之后是三个文件,分区表是文件夹.桶表和分区表目的都是为了把数据进行划分,只是划分的方式不一样,一个是从业务字段的角度来划分,一个是抛弃了业务字段从纯数据的角度来进行划分,纯数据的角度和查询就不搭界了,主要就是用于抽样,表连接.


<think>嗯,用户问的是Hive中删除数据时,内部表外部表哪个会同时删除元数据。我需要先回忆一下Hive内部表外部表区别内部表(管理)的数据Hive管理,存储在Hive的默认仓库目录里,删除内部表的时候,元数据实际数据都会被删除。而外部表数据存储在外部位置,比如HDFS的其他目录,删除外部表的时候,Hive只会删除元数据,而实际的数据文件不会被删除。 所以问题是在删除数据时,比如执行DROP TABLE命令,内部表会删除元数据数据,而外部表只删除元数据。用户可能是在处理数据清理时,需要了解这两种区别,避免误删数据。用户可能的实际场景是他们在设计Hive结构,需要决定使用内部表还是外部表,特别是在需要考虑数据生命周期管理的时候。比如,如果数据是临时的,用内部表可能更合适,因为删除时会自动清理数据;如果是共享的数据,用外部表更安全,防止误删。 另外,用户可能对Hive元数据存储有疑问,比如元数据存在哪里,是MySQL还是其他数据库,但这里的问题可能更关注于删除操作对元数据的影响。需要明确回答的是,当删除时,内部表元数据数据都被删除,外部表只删元数据。可能还需要提到TRUNCATE命令的情况,不过用户的问题主要是关于DROP TABLE的情况。 需要确认是否有其他情况,比如使用分区表,删除分区时是否会有不同,但用户的问题比较基础,可能不需要深入到这里。最后确保回答准确,结构清晰,用例子说明会更清楚。</think>在 Hive 中,**内部表(Managed Table)****外部表(External Table)**在删除数据时的行为不同,具体如下: ### 1. **内部表(Managed Table)** - **删除操作行为**: 当使用 `DROP TABLE` 删除内部表时,Hive **会同时删除元数据(存储在 Metastore 中)实际存储的数据文件(如 HDFS 上的数据)**。 - **示例**: ```sql DROP TABLE managed_table; -- 元数据数据都会被删除 ``` ### 2. **外部表(External Table)** - **删除操作行为**: 当使用 `DROP TABLE` 删除外部表时,Hive **只会删除元数据(Metastore 中的信息),而实际存储的数据文件(如 HDFS 上的数据)仍然保留**。 - **示例**: ```sql DROP TABLE external_table; -- 仅删除元数据数据文件保留 ``` --- ### 关键区别总结 | 操作 | 内部表(Managed Table) | 外部表(External Table) | |---------------------|------------------------|-------------------------| | `DROP TABLE` | 删除元数据 + 数据文件 | 仅删除元数据 | | 数据生命周期管理 | Hive 全权管理 | 用户自行管理(数据保留) | --- ### 使用场景建议 - **内部表**:适合临时数据或需要 Hive 自动管理数据生命周期的场景。 - **外部表**:适合其他工具(如 Spark、HBase)共享数据,或需要长期保留原始数据的场景。 如果需要删除外部表数据文件,需手动清理(如通过 `hadoop fs -rm` 命令)。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老马识途2.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值