理解Hive表(Hive Table)

本文深入介绍了Hive表的内部表与外部表的区别,强调了数据管理与删除行为的不同。同时,文章详细讨论了分区和Buckets的概念,以及它们如何提高查询效率。此外,还探讨了Hive表的存储格式,包括默认的文本格式、二进制格式如Avro和Parquet,以及如何使用自定义SerDe和Storage Handler。最后,文章涵盖了数据导入、表修改和删除的操作,提供了一种理解和操作Hive表的全面视角。
摘要由CSDN通过智能技术生成

Hive表逻辑上有表的数据和相关的元数据组成。元数据描述表的结构,索引等信息。数据通常存放在HDFS中,虽然任意的Hadoop文件系统都能支持,例如Amazon的S3或者而本地文件系统。元数据则存在关系型数据库中,嵌入式的默认使用Derby,MySQL是一种很常用的方案。

许多关系型数据库都提供了命名空间的概念,用于划分不同的数据库或者Schema。例如MySQL支持的Database概念,PostgreSQL支持的namespace概念。Hive同样提供了这种逻辑划分功能,相关的语句包括:

CREATE DATABASE dbname;
USE dbname;
DROP DATABASE dbname;

表的全称可以通过dbname.tablename来访问,如果没有指定dbname,默认为default。show databasesshow tables命令可用于查看数据库以及数据库中的表。

image_1aou0pbctok3t9trtu5v4949.png-14.1kB

1. 内部表与外部表

在Hive中创建表的时候,默认情况下Hive将会管理表的数据,也就是将数据移动到对应的warehouse目录下。也可以创建 外部表,告诉Hive将表指向warehouse目录外的数据。

这两种类型的不同首先表现在LOAD和DROP语句的行为上。考虑下面的语句:

CREATE TABLE managed_table(dummy ,STRING);
LOAD DATA INPATH '/user/root/data.txt' INTO table managed_table;

上述语句会将hdfs://user/root/data.txt移动到Hive的对应目录hdfs://user/hive/warehouse/managed_table 。载入数据的速度非常快,因此Hive只是把数据移动到对应的目录,不会对数据是否符合定义的Schema做校验,这个工作通常在读取的时候进行,成为Schema On Read。

数据表使用DROP语句删除后,其数据和表的元数据都被删除,不再存在,这就是Hive Managed的意思。

DROP TABLE managed_table;

外部表则不一样,数据的创建和删除完全由自己控制,Hive不管理这些数据。数据的位置在CREATE时指定:

CREATE EXTERNAL TABLE external_table (dummy,STRING)
    LOCATION '/user/root/external_table';

LOAD DATA INPATH '/user/root/data.txt' INTO TABLE external_table;

指定EXTERNAL关键字后,Hive不会把数据移动到warehouse目录中。事实上,Hive甚至不会校验外部表的目录是否存在。这使得我们可以在创建表格之后再创建数据。当删除外部表时,Hive只删除元数据,而外部数据不动。

选择内部表还是外部表?大多数情况下,这两者的区别不是很明显。如果数据的所有处理都在Hive中进行,那么更倾向于选择内部表。但是如果Hive和其他工具针对相同的数据集做处理,外部表更合适。一种常见的模式是使用外部表访问存储的HDFS(通常由其他工具创建)中的初始数据,然后使用Hive转换数据并将其结果放在内部表中。相反,外部表可以用于将Hive的处理结果导出供其他应用使用。使用外部表的另一种场景是针对一个数据集,关联多个Schema。

2. 分区与Buckets

Hive将表划分为分区,Partition根据分区字段进行。分区可以让数据的部分查询变得更快。表或者分区可以进一步被划分为buckets,bucket通常在原始数据中加入一些额外的结构,这些结构可以用于高效查询。例如,基于用户id的分桶可以使用基于用户的查询非常快。

分区

假设日志数据中,每条记录都带有时间戳。如果根据时间来分区,那么同一天的数据将被划分到同一个Partition中。针对每一天或者某几天数据的查询将会变得很高效,因为只需要扫描对应分区中的文件。分区并不会导致跨度大的查询变得低效。

分区可以通过多个维度来进行。例如通过日期划分之后,我们可以根据国家进一步划分。

分区在创建表的时候定义,使用 PARTITIONED BY从句,该从句接受一个字段列表:

CREATE TABLE logs (ts BIGINT , line STRING)
PARTITIONED BY (dt STRING,country STRING);

当导入数据到分区表时,分区的值被显式指定:

LOAD DATA INPATH '/user/root/path'
INTO TABLE logs
PARTITION (dt='2001-01-01',country='GB');

在文件系统上,分区作为表目录的下一级目录存在:

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值