hive内外表、分区表及桶表

本文详细介绍了Hive中的数据库、表、分区和桶的概念及其应用。对比内部表与外部表的区别,并提供了创建和使用的实例。此外还阐述了如何通过分区和桶提升查询效率。

hive库、表、分区、桶的一些概念:
Databases:数据库,概念等同于关系型数据库的Schema;
Tables:表,概念等同于关系型数据库的表;
Partitions:分区,概念类似于关系型数据库的表分区,便于提高效率;
Buckets (or Clusters):分桶,同一个分区内的数据还可以细分,将相同的KEY再划分至一个桶中,
这个有点类似于HASH分区,只不过这里是HASH分桶,也有点类似子分区吧,进一步提高效率;

Hive中的表分为内部表(MANAGED_TABLE)和外部表(EXTERNAL_TABLE)。默认为内部表;
区别: 内部表DROP时候会删除HDFS上的数据;
       外部表DROP时候不会删除HDFS上的数据;
内部表适用场景:适用于Hive中间表、结果表、以及不需要从外部(如本地文件、HDFS)load数据的情况。或者从外部或者
其他表insert到内部表中。
外部表适用场景:源表,需要定期将外部数据映射到表中。
适用场景举例说明:每天将收集到的网站日志定期流入HDFS文本文件,一天一个目录,
在Hive中建立外部表作为源表,通过添加分区的方式,将每天HDFS上的原始日志映射到外部表的天分区中,
在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。

简单内表创建:
create table dd (name string , age string) location '/input/table_data';  不指定external默认创建内部表
并且会在hdfs上新建一个dd表的数据存放地 若不指定location会默认在/user/hive/warehouse/目录对应的库下创建。
load data inpath '/input/data' into table dd;  加载数据到表中。

外部表的简单创建:
create external table aa (name string , age string);   会在/user/hive/warehouse/对应的库下面建一个表目录
load data inpath '/input/edata' into table aa;  
删除这个外部表后,
/user/hive/warehouse/对应的库下面建一个表目录下的数据不会删除,但是/input/edata/下的数据在上一步load后已经没有了!
数据的位置发生了变化!本质是load一个hdfs上的数据时会转移数据!

小结hive内外表区别

1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下(如果指定了location的话),
也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样;
     
2、在删除内部表的时候,Hive将会把属于表的元数据和数据全部删掉;
而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!

3. 在创建内部表或外部表时加上location 的效果是一样的,只不过表目录的位置不同而已,
加上partition用法也一样,只不过表目录下会有分区目录而已,
load data local inpath直接把本地文件系统的数据上传到hdfs上,
有location上传到location指定的位置上,没有的话上传到hive默认配置的数据仓库中。
加入分区的原因:
1、加入分区避免Hive Select查询中扫描整个表内容,会消耗很多时间做没必要的工作。
(例如每一天的日志存放在一个分区中,这样根据特定的日期查询)

2、一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。

桶表
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。
Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

桶是以文件的形式存放在表或者分区的目录下。

把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。
具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。
比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。
那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,
如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

分区表创建
CREATE EXTERNAL TABLE IF NOT EXISTS data_table(
ROWKEY        STRING,
STATION       INT,
MONTH         INT,
DAY           INT,
HOUR          INT,
MINUTE        INT
)
PARTITIONED BY (YEAR INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,’
LINES TERMINATED BY ‘\n’
STORED AS TEXTFILE;


关键字STORED AS: 指定表在HDFS上的文件存储格式,可选的文件存储格式有:
TEXTFILE:文本默认值.SEQUENCEFILE:二进制序列文件 。RCFILE、ORC、PARQUET:
几种列式存储格式文件。关键字LOCATION: 指定表在HDFS上的存储位置
hiveSQL和mysql语法相像,对于大小写不敏感,包括函数。
CREATE EXTERNAL TABLE test1 (
id                    INT,
ip                    STRING COMMENT '访问者IP',
avg_view_depth        DECIMAL(5,1),
bounce_rate           DECIMAL(6,5)
) COMMENT '表详情注释'
PARTITIONED BY (day STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS textfile
LOCATION 'hdfs://user/hive/warehose/';

关键字EXTERNAL:表示该表为外部表,如果不指定EXTERNAL关键字,则表示内部表 .
关键字COMMENT: 为表和列添加注释。
关键字PARTITIONED BY: 表示该表为分区表,分区字段为day,类型为string。
关键字ROW FORMAT DELIMITED: 指定表的分隔符,通常后面要与以下关键字连用:
FIELDS TERMINATED BY ',':指定每行中字段分隔符为逗号。
LINES TERMINATED BY '\n':指定行分隔符
COLLECTION ITEMS TERMINATED BY ',' :指定集合中元素之间的分隔符 。
MAP KEYS TERMINATED BY ':':指定数据中Map类型的Key与Value之间的分隔符,

<think>Hive内部外部的核心差异主要在数据生命周期管理、存储位置控制及数据删除行为三个方面。 根据引用[1][2][4],内部(Managed Table)的数据完全由Hive管理,删除时会同时删除元数据HDFS上的数据文件;外部(External Table)仅管理元数据,删除时只删除元数据,HDFS数据文件保留。引用[3]进一步强调,外部的数据由HDFS管理,适合需要避免误删或数据共享的场景。 存储位置方面,引用[2][4]指出:内部默认存储在Hive配置的仓路径(如`/user/hive/warehouse`),可通过`location`覆盖;外部创建时必须显式指定数据路径(`LOCATION '/path'`)。 此外引用[3]补充了关键行为差异:使用`LOAD DATA`加载数据到内部时,Hive会将源文件移动到目录;而外部仅记录路径,不移动原始数据。 下面是结构化对比: | **维度** | **内部** | **外部** | |------------------|-------------------------------------|-------------------------------------| | **创建语法** | `CREATE TABLE t (...)` | `CREATE EXTERNAL TABLE t (...) LOCATION '/path'` | | **数据归属** | Hive管理 | HDFS管理 | | **删除行为** | 删除元数据****数据文件 | 仅删除元数据 | | **存储位置** | 默认`hive.metastore.warehouse.dir` | 必须显式指定`LOCATION` | | **数据加载** | `LOAD DATA`移动源文件到目录 | `LOAD DATA`不移动文件(仅映射路径) | | **共享性** | 弱(数据与强绑定) | 强(多系统可共享数据) | ### 使用场景建议 综合引用[2][3][4]: - **优先使用外部**: - 原始日志/埋点数据(防误删) - 需被Spark/Flink等工具共享的数据 - 长期保留的基(如ODS层) - **选择内部**: - ETL中间(临时生命周期) - 统计结果Hive独占管理) - 需要自动清理的历史数据(如保留最近N天分区) 例如引用[3]提到:"每天采集的ng日志埋点日志建议使用外部,因误删后恢复困难"。而业务数据导入后,若无需共享且可重建,则内部更便于紧凑管理。 ### 操作示例 1. **创建外部**(指定HDFS路径): ```sql CREATE EXTERNAL TABLE logs ( id STRING, content STRING ) LOCATION '/data/logs'; ``` 2. **创建内部**(默认路径): ```sql CREATE TABLE results ( date STRING, pv INT ) PARTITIONED BY (dt STRING); ``` §§相关问题§§ 1. Hive内部数据被删除后如何恢复? 2. 如何将Hive外部的数据迁移到另一个存储系统? 3. Hive分区管理与内部/外部的选择有什么关系? </think>### Hive内部与外部的区别、特点及使用场景 根据引用内容[1][2][3][4],Hive内部(Managed Table)外部(External Table)的核心差异主要体现在**数据生命周期管理****元数据操作行为**上,具体对比如下: --- #### **1. 核心区别对比** | **维度** | **内部** | **外部** | |------------------|-------------------------------------|-------------------------------------| | **创建语法** | `CREATE TABLE t (...)` | `CREATE EXTERNAL TABLE t (...) LOCATION '/path'` | | **数据归属权** | Hive完全管理(存储+元数据) | HDFS管理数据,Hive仅管理元数据 | | **删除行为** | 删除时**同时删除元数据数据文件** | 删除时**仅删除元数据,保留数据文件** | | **默认存储路径** | `hive.metastore.warehouse.dir` | 必须显式指定`LOCATION`(如`/data/logs`) | | **数据加载** | `LOAD DATA`会**移动**原始文件到目录 | `LOAD DATA`**不移动**文件(仅映射路径) | | **数据安全** | 误删后数据难恢复 | 误删后可通过重建恢复数据 | > 💡 **关键验证**: > 删除内部后,HDFS数据被清除(类似`rm -rf`);删除外部后,HDFS数据保留,仅删除Metastore中的定义[^2][^4]。 --- #### **2. 核心特点** 1. **内部特点**: - 数据与元数据强绑定,适合Hive独占管理的场景 - ETL过程中自动清理中间数据(如临时) - 默认路径统一管理,简化运维[^2] 2. **外部特点**: - **数据共享**:允许多个工具(如Spark、Flink)直接访问HDFS数据 - **防误删**:删除操作不影响底层数据文件 - **灵活迁移**:数据目录可独立于Hive存在(如业务系统直接写入HDFS)[^3][^4] --- #### **3. 使用场景推荐** 根据引用[2][3][4]的实践建议: - **优先使用外部的场景**: - **原始数据层**:日志数据(如Nginx日志、埋点日志),避免误删导致数据丢失 - **多系统共享**:需要被Spark/Flink等工具直接读取的数据 - **长期存储**:历史归档数据或需跨团队共享的基 - **优先使用内部的场景**: - **ETL中间**:临时计算的中间结果(自动清理节省存储) - **统计结果**:报数据等Hive独占管理的数据 - **生命周期短的数据**:如临时测试或每日覆盖的分区表 > 📌 **黄金准则**(引用[3]): > - **"全量用内部,增量用外部"**:静态数据用内部,频繁更新的增量数据用外部 > - **"日志外部,业务内部"**:原始日志必用外部,业务数据根据共享需求选择 --- #### **4. 操作示例** ```sql -- 内部 (自动管理存储路径) CREATE TABLE managed_table ( id INT, name STRING ) PARTITIONED BY (dt STRING); -- 外部 (需指定数据位置) CREATE EXTERNAL TABLE external_logs ( ip STRING, url STRING ) LOCATION '/data/raw/logs'; ``` > ️ **注意**: > 对内部执行 `DROP TABLE managed_table` 会删除HDFS上的数据; > 对外部执行 `DROP TABLE external_logs` 仅删除元数据,`/data/raw/logs` 下的文件保留[^2][^4]。 --- #### **5. 设计决策流程图** ```mermaid graph TD A[需长期保留且多系统共享?] -- Yes
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值