五、Hive表类型、分区及数据加载

在 Hive 中高效构建、管理和查询数据仓库,核心在于精准运用表类型(内部/外部)分区策略(静态/动态/多重)。这不仅决定数据的生命周期归属,更是优化海量数据查询性能关键手段

一、表的身份权责:内部表 vs 外部表

内部表 (Managed Table)

  • 定义: Hive 默认。Hive 同时管理元数据和 HDFS 数据(通常在仓库目录创建专属子目录)。
  • 数据控制: Hive 拥有并控制数据完整生命周期
  • 生命周期: DROP TABLE 会删除元数据 HDFS 数据。
  • 适用: 临时表中间结果,或完全由 Hive 控制的数据。

代码:创建内部表

CREATE TABLE clicks_internal (session_id STRING,click_url STRING
) 
COMMENT '内部表,数据由Hive管理';

外部表 (External Table)

  • 定义: 需显式EXTERNAL必须LOCATION 指定 HDFS 路径。Hive 仅管理元数据
  • 数据控制: Hive 不拥有数据,数据保留LOCATION 原始位置
  • 生命周期: DROP TABLE 仅删元数据,HDFS 数据保留
  • 适用: 管理已存在数据、需共享数据、防误删关键数据。

代码:创建外部表

CREATE EXTERNAL TABLE impressions_external (ad_id STRING,user_id STRING)COMMENT '外部表,数据独立于Hive'
LOCATION '/data/raw/impressions'; -- 指定数据存储路径

关键操作:若手动在外部表 LOCATION 路径下增删分区目录,需执行 MSCK REPAIR TABLE table_name; 同步元数据

代码:修复外部表分区

MSCK REPAIR TABLE impressions_external;

核心对比: DROP TABLE 是否删 HDFS 数据;Hive 是否移动/拥有数据。

二、查询加速核心:分区表及其数据加载

分区通过分区键大表数据物理划分到 HDFS 不同子目录,实现查询剪枝极大提升性能。

创建分区表

  • 分区键不是表中实际存储的列,但表现如普通列。
  • 支持多重分区,形成层级目录

代码:创建单分区表

CREATE TABLE daily_activity (user_id BIGINT,type STRING)
PARTITIONED BY (dt DATE);

代码:创建多重分区表

CREATE TABLE page_views (user_id BIGINT, page_url STRING)
PARTITIONED BY (view_date DATE, country STRING) -- 按日期和国家分区
STORED AS ORC;

数据加载到分区表

关键:必须确保数据被放入正确的分区目录。Hive 不推荐直接用 hadoop fs -put 到分区目录(因为这不会更新元数据,除非后续 MSCK REPAIRALTER TABLE ADD PARTITION)。主要有两种方式:

1. 静态分区加载

  • 机制: 在加载命令中 明确指定目标分区的所有键值。Hive 知道数据确切的目的地。

  • 方式一:LOAD DATA (通常用于加载已准备好的文件到特定分区)

    • LOCAL 关键字表示文件在运行 Hive 命令本地机器上(对 HiveServer2 来说是 Server 所在机器)。省略 LOCAL 表示文件在 HDFS 上。
    • OVERWRITE先清空目标分区再加载。省略则追加

    代码:从本地加载到单分区

    LOAD DATA LOCAL INPATH '/path/to/local/activity_20231103.txt'
    OVERWRITE INTO TABLE daily_activity
    PARTITION (dt='2023-11-03');
    

    代码:从 HDFS 加载到多重分区

    LOAD DATA INPATH '/user/data/views_us_20231103'
    INTO TABLE page_views
    PARTITION (view_date='2023-11-03', country='US');
    
  • 方式二:INSERT OVERWRITE/INTO ... PARTITION (通常用于从其他表查询结果并写入特定分区)

    • INSERT OVERWRITE 覆盖分区,INSERT INTO 追加(Hive 0.14+)。

    代码:从源表查询插入到特定分区

    INSERT OVERWRITE TABLE page_views
    PARTITION (view_date='2023-11-03', country='CA') -- 静态指定分区
    SELECT user_id, page_url
    FROM source_views
    WHERE event_date = '2023-11-03' AND user_country = 'CA';
    
  • 静态分区特点: 控制精准;适合分区值已知/固定;分区组合多语句繁琐

2. 动态分区加载

  • 机制: 仅用于 INSERT ... SELECT。在 PARTITION 子句中不指定(或部分不指定)分区键的值,让 Hive 根据 SELECT 查询结果对应列必须是最后几列)的实际值自动推断创建分区目录并写入数据
  • 核心配置:
    • SET hive.exec.dynamic.partition=true; (必须启用)
    • SET hive.exec.dynamic.partition.mode=nonstrict; (推荐。允许所有分区键动态。strict 模式至少需一个静态键,防误操作)
    • (可选) hive.exec.max.dynamic.partitions... 等参数控制资源
  • SELECT 列顺序: 极其重要SELECT 列表中的最后几列 必须按照 PARTITION 子句中动态分区键顺序排列,且类型兼容

代码:全动态分区加载 (单分区键)

SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT OVERWRITE TABLE daily_activity
PARTITION (dt) -- dt 是动态分区键
SELECT user_id, type, event_date -- event_date 的值将决定 dt 分区值
FROM source_table;

代码:全动态分区加载 (多重分区键)

SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT OVERWRITE TABLE page_views
PARTITION (view_date, country) -- view_date, country 都是动态分区键
SELECT user_id, page_url, event_date, user_country -- 最后两列对应分区键
FROM source_views;

代码:混合分区加载 (多重分区,静态+动态)

-- 静态指定 view_date, 动态指定 country
INSERT OVERWRITE TABLE page_views
PARTITION (view_date='2023-11-03', country) -- 静态在前,动态在后
SELECT user_id, page_url, user_country -- 最后一列对应动态分区键 country
FROM source_views
WHERE event_date = '2023-11-03';
  • 动态分区特点: 自动化便捷,尤其适合批量转换或分区值多样/未知需小心配置谨防意外产生过多小分区数据倾斜

手动管理分区

  • 除加载外,可直接操作分区元数据。

代码:手动添加/删除/修改分区

ALTER TABLE page_views ADD IF NOT EXISTS PARTITION (view_date='2023-11-04', country='CA');
ALTER TABLE page_views DROP IF EXISTS PARTITION (view_date='2023-11-01', country='UK');
ALTER TABLE page_views PARTITION (view_date='2023-11-03', country='US') SET LOCATION 'hdfs:///new/path/...'; -- 修改路径 (不移动数据)

三、实战演练与深度思考

练习题 1:
/data/shared_logs 有需长期保留、多部门共享的日志。应创建内部表还是外部表?为何?若手动在 HDFS 增新分区目录及数据,如何让 Hive 感知?

练习题 2:
源表 orders_source (含 order_id, user_id, order_amount, order_country, order_date DATE)。创建按国家和日期分区的外部表 orders_partitioned (ORC格式,数据存 /data/orders_part),并写动态分区导入数据的 INSERT 语句。

练习题 3:
静态分区 PARTITION 子句的值与源数据列值必须一致吗?动态分区呢?解释原因。

练习题 4:
daily_activitydt 分区。SELECT COUNT(*) FROM daily_activity WHERE user_id = 123; 会利用分区提速吗?为什么?如何设计能让基于 user_id 的查询提速?

练习题 5:
解释 hive.exec.dynamic.partition.mode=strictnonstrict 的区别及 strict 设计意图。

练习题 6:
如何将内部表 prod_data 无风险转为外部表?写 ALTER 语句。

练习题 7 (代码):
查看 orders_partitioned 表的完整 DDL (创建语句)。

练习题 8 (代码):
列出 orders_partitioned 表中 order_country='CA' 的所有分区

练习题 9 (代码):
为分区表 metrics_table (分区键 report_date DATE) 批量添加 2023-12-012023-12-05 的分区元数据(假设 HDFS 目录结构已备好)。

练习题 10 (代码):
orders_partitioned 表中一次性删除多个分区:country='JP', date='2023-06-18'country='KR', date='2023-06-19'

练习题 11 (代码):
写查询计算 orders_partitioned 表中 order_country 为 ‘DE’ 或 ‘FR’,且 order_date 在 2023年第三季度的总订单数。

练习题 12 (代码):
查看 page_views 表的分区键信息。

练习题 13 (代码):
使用 INSERT OVERWRITE DIRECTORYpage_views特定分区 (date='2023-11-03', country='US') 数据导出到本地目录 /tmp/exported_data,字段分隔符为 |

练习题 14 (代码):
假设 daily_activity 表你想按 dttype 进行动态分区,源表 source_table 包含 user_id, activity_type, event_date。写出正确的 INSERT … SELECT 语句,确保动态分区列顺序正确

练习题 15 (代码):
创建一个内部表 user_profiles,包含 user_id INT, profile MAP<STRING,STRING>,字段分隔符为 ,,Map 键值对分隔符为 #,Map 内 KV 分隔符为 :


答案解析

答案 1:
外部表。原因:数据独立、需共享/保留DROP 安全。执行 MSCK REPAIR TABLE table_name; 同步新分区

答案 2:
DDL:

CREATE EXTERNAL TABLE orders_partitioned (
order_id BIGINT, 
user_id BIGINT, 
order_amount DECIMAL(18,2))
PARTITIONED BY (order_country STRING, order_date DATE) STORED AS ORC
LOCATION '/data/orders_part';

INSERT:

SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT OVERWRITE TABLE orders_partitioned PARTITION (order_country, order_date)
SELECT order_id, user_id, order_amount, order_country, order_date FROM orders_source;

答案 3:

  • 静态不必。指定值决定目录。
  • 动态必须。分区值源自 SELECT 列实际值

答案 4:
不会WHERE 未用分区键 dt。基于 user_id 提速可考虑分桶 (CLUSTERED BY (user_id) ...)。

答案 5:
strict 要求至少一个静态分区键。意图防误操作(如忘加 WHERE)全表扫描海量分区nonstrict 无此限制

答案 6:

ALTER TABLE prod_data SET TBLPROPERTIES('EXTERNAL'='TRUE');

答案 7:

SHOW CREATE TABLE orders_partitioned;

答案 8:

SHOW PARTITIONS orders_partitioned PARTITION(order_country='CA');

答案 9:
标准 HiveQL 不支持日期范围批量 ADD PARTITION。需脚本循环MSCK REPAIR
脚本思路 (伪代码):

for day in {01..05}; do
hive -e "ALTER TABLE metrics_table ADD IF NOT EXISTS PARTITION (report_date='2023-12-${day}');"
done

答案 10:
执行多次 ALTER TABLE ... DROP PARTITION

ALTER TABLE orders_partitioned DROP IF EXISTS PARTITION (order_country='JP', order_date='2023-06-18');
ALTER TABLE orders_partitioned DROP IF EXISTS PARTITION (order_country='KR', order_date='2023-06-19');

答案 11:

SELECT COUNT(*) FROM orders_partitioned
WHERE order_country IN ('DE', 'FR')
AND order_date >= '2023-07-01' AND order_date <= '2023-09-30';

答案 12:

DESCRIBE FORMATTED page_views; -- 查看 "# Partition Information"
-- 或
DESCRIBE page_views; -- 分区键列在最后

答案 13:

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/exported_data' -- LOCAL 指本地
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
SELECT user_id, page_url, view_time -- 选择需要的列,而不是 *
FROM page_views
WHERE view_date='2023-11-03' AND country='US';

答案 14:
需要创建 daily_activity 表时定义分区键为 PARTITIONED BY (dt DATE, type STRING)

SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT OVERWRITE TABLE daily_activity
PARTITION (dt, type) -- dt 和 type 都是动态
SELECT user_id, event_date, activity_type -- 最后两列 event_date, activity_type 对应分区键
FROM source_table;

答案 15:

CREATE TABLE user_profiles (
user_id INT,
profile MAP<STRING,STRING>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '#' -- Map 内 KVP 分隔符
MAP KEYS TERMINATED BY ':'; -- Map 内 K 和 V 分隔符

结语:因地制宜,优化存储与查询

精准运用 Hive 的表类型分区策略数据仓库建设性能调优核心。根据数据生命周期、共享需求、查询模式因素审慎设计,能显著提升数据管理效率查询响应

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/82686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++色彩博弈的史诗:红黑树

文章目录 1.红黑树的概念2.红黑树的结构3.红黑树的插入4.红黑树的删除5.红黑树与AVL树的比较6.红黑树的验证希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 红黑树是一种自平衡二叉查找树&#xff0c;每个节点都带有颜色属性&#xff0c;颜色或为…

基于STM32、HAL库的CH342F USB转UART收发器 驱动程序设计

一、简介: CH342F是一款USB转串口芯片,由南京沁恒电子(WCH)生产,具有以下特点: 支持USB转UART、IrDA红外或SPI接口 内置时钟,无需外部晶振 支持5V和3.3V电源电压 最高支持3Mbps波特率 支持常用的MODEM联络信号 内置EEPROM,可配置设备VID/PID/序列号等 二、硬件接口: C…

项目功能-图片清理(上)

一、图片存储介绍 在实际开发中&#xff0c;我们会有很多处理不同功能的服务器。例如&#xff1a; 应用服务器&#xff1a;负责部署我们的应用 数据库服务器&#xff1a;运行我们的数据库 文件服务器&#xff1a;负责存储用户上传文件的服务器 分服务器处理的目的是让服务…

创建三个网络,分别使用RIP、OSPF、静态,并每个网络10个电脑。使用DHCP分配IP

DHCP 自动分配IP&#xff0c;集中管理&#xff0c;提高效率 在路由器中设置 Router>en Router#conf t Router(config)#ip dhcp pool ip30 //创建DHCP地址池 Router(dhcp-config)#network 192.168.30.0 255.255.255.0 // 配置网络地址和子网掩码 Router(dhcp-config)#defa…

如何使用 WMIC 命令在 Windows 11 或 10 上卸载软件

如果您正在寻找一个命令提示符或 PowerShell 命令来卸载 Windows 应用程序,那么使用 wmic(Windows Management Instrumentation Command-line)是一种强大的技术,尤其是在处理难以卸载的程序或自动化卸载过程时。在本教程中,我们将学习如何使用 wmic 来卸载软件。 先决条件…

FEKO许可证的安全与合规性

在电磁仿真领域&#xff0c;FEKO软件因其出类拔萃的性能和广泛的应用场景&#xff0c;赢得了全球用户的广泛赞誉。但在这背后&#xff0c;是什么让FEKO在众多竞争者中脱颖而出&#xff1f;答案是其许可证的安全与合规性。它们不仅为用户提供了坚固的保障&#xff0c;更确保了用…

ESP32开发入门(九):HTTP服务器开发实践

一、HTTP服务器基础 1.1 什么是HTTP服务器&#xff1f; HTTP服务器是能够处理HTTP请求并返回响应的网络服务程序。在物联网应用中&#xff0c;ESP32可以作为轻量级HTTP服务器&#xff0c;直接接收来自客户端(如浏览器、手机APP)的请求。 1.2 ESP32作为HTTP服务器的特点 轻量…

《棒球百科》MLB棒球公益课·棒球1号位

MLB&#xff08;美国职业棒球大联盟&#xff09;的棒球公益课通过推广棒球运动、普及体育教育&#xff0c;对全球多个地区产生了多层次的影响&#xff1a; 1. 体育文化推广 非传统棒球地区的普及&#xff1a;在棒球基础较弱的地区&#xff08;如中国、欧洲部分国家&#xff09…

Baumer工业相机堡盟工业相机的工业视觉是否可以在室外可以做视觉检测项目

Baumer工业相机堡盟工业相机的工业视觉是否可以在室外可以做视觉检测项目 Baumer工业相机​视觉检测项目为什么偏爱“室内环境”&#xff1f;​工业视觉中为什么倾向于室内环境**保障人员与设备安全**&#xff1a;室内环境可以提供更好的安全保障&#xff0c;避免检测设备和人员…

1. 使用 IntelliJ IDEA 创建 React 项目:创建 React 项目界面详解;配置 Yarn 为包管理器

1. 使用 IntelliJ IDEA 创建 React 项目&#xff1a;创建 React 项目界面详解&#xff1b;配置 Yarn 为包管理器 &#x1f9e9; 使用 IntelliJ IDEA 创建 React 项目&#xff08;附 Yarn 配置与 Vite 建议&#xff09;&#x1f4f7; 创建 React 项目界面详解1️⃣ Name&#xf…

C++GO语言微服务之用户信息处理②

目录 01 03-获取用户信息-上 02 04-获取用户信息-下 03 05-更新用户名实现 01 06-中间件简介和中间件类型 02 07-中间件测试和模型分析 03 08-中间件测试案例和小结 04 09-项目使用中间件 01 03-获取用户信息-上 ## Cookie操作 ### 设置Cookie go func (c *Context) …

QMK键盘固件开发全解析:QMK 固件开发的最新架构和规范(2025最新版)

QMK键盘固件开发全解析:QMK 固件开发的最新架构和规范(2025最新版) 📚 前言概述 QMK(Quantum Mechanical Keyboard)作为目前开源键盘固件领域的"扛把子",凭借其强大的功能和活跃的社区支持,已经成为众多DIY键盘爱好者的首选开发框架。无论是入门级玩家还是资…

极狐GitLab 容器镜像仓库功能介绍

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 极狐GitLab 容器镜像库 (BASIC ALL) 您可以使用集成的容器镜像库&#xff0c;来存储每个极狐GitLab 项目的容器镜像。 要为您…

Umi+React+Xrender+Hsf项目开发总结

一、菜单路由配置 1.umirc.ts 中的路由配置 .umirc.ts 文件是 UmiJS 框架中的一个配置文件&#xff0c;用于配置应用的全局设置&#xff0c;包括但不限于路由、插件、样式等。 import { defineConfig } from umi; import config from ./def/config;export default defineCon…

【运维】基于Python打造分布式系统日志聚合与分析利器

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在分布式系统中,日志数据分散在多个节点,管理和分析变得复杂。本文详细介绍如何基于Python开发一个日志聚合与分析工具,结合Logstash和F…

Python实战:海量获取京东商品信息

在数据驱动的商业时代&#xff0c;数据就是最宝贵的资源。对于电商从业者、市场分析师而言&#xff0c;从京东这类大型电商平台获取商品信息&#xff0c;能够为市场调研、竞品分析、销售策略制定提供重要依据。今天&#xff0c;就来分享如何用Python实现京东商品信息的海量获取…

聊一聊常见的超时问题:timeout

大家好&#xff0c;我是G探险者&#xff01; 在日常开发中&#xff0c;“超时&#xff08;Timeout&#xff09;”类错误是开发者们经常遇到的问题。无论是调用第三方服务、访问数据库&#xff0c;还是并发任务处理&#xff0c;都可能因超时而导致请求失败或系统异常。 本文将系…

创建型模式:工厂方法(Factory Method)模式

一、简介 工厂方法(Factory Method)模式是一种创建型设计模式,它定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。在 C# 中,工厂方法模式提供了一种更灵活的对象创建方式,将对象的创建和使用分离,提高了代码的可维护性和…

外网访问内网海康威视监控视频的方案:WebRTC + Coturn 搭建

外网访问内网海康威视监控视频的方案&#xff1a;WebRTC Coturn 需求背景 在仓库中有海康威视的监控摄像头&#xff0c;内网中是可以直接访问到监控摄像的画面&#xff0c;由于项目的需求&#xff0c;需要在外网中也能看到监控画面。 实现这个功能的意义在于远程操控设备的…

Redis 8.0正式发布,再次开源为哪般?

Redis 8.0 已经于 2025 年 5 月 1 日正式发布&#xff0c;除了一些新功能和性能改进之外&#xff0c;一个非常重要的改变就是新增了开源的 AGPLv3 协议支持&#xff0c;再次回归开源社区。 为什么说再次呢&#xff1f;这个需要从 2024 年 3 月份 Redis 7.4 说起&#xff0c;因为…