【大数据】HiveQL的数据操作

本文详细介绍了如何使用HiveQL进行数据装载,包括LOAD DATA LOCAL INPATH与INSERT OVERWRITE TABLE操作,以及动态分区和创建表的同时加载数据。还涉及了导出数据的方法。重点在于数据加载策略和Hive的分区管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HiveQL的数据操作

因为 Hive 没有行级别的数据插入、数据更新和删除操作,那么往表中装载数据的唯一途径就是使用一种 大量 的数据装载操作。或者通过其他方式仅仅将文件写入到正确的目录下。

1. 向管理表中装载数据

LOAD DATA LOCAL INPATH '${env:HOME}/california-employees'
OVERWRITE INTO TABLE employees
PARTITION (country = 'US', state = 'CA');
  • 如果分区目录不存在的话,这个命令会先创建分区目录,然后再将数据拷贝到该目录下。
  • 如果目标表是非分区表,那么语句中应该省略 PARTITION 字句。
  • 通常情况下指定的路径应该是一个目录,而不是单个独立的文件。Hive 会将所有文件都拷贝到这个目录下。
  • 如果使用了 LOCAL 这个关键字,那么这个路径应该为本地文件系统路径。如果省略掉 LOCAL 关键字,那么这个路径应该是分布式文件系统中的路径。
  • 如果用户指定了 OVERWRITE 关键字,那么目标文件夹中之前存在的数据将会被先删除掉。如果没有这个关键字,仅仅会把新增的文件增加到目标文件夹中,而不会删除之前的数据。然而,如果目标文件夹中已经存在和装载的文件同名的文件,那么旧的同名文件将会被覆盖重写(Hive v0.9.0版本之前的操作),会产生数据丢失。
  • 对于 INPATH 子句中使用的文件路径还有一个限制,就是这个路径下不可以包含任何文件夹。
  • Hive 并不会验证用户装载的数据和表的模式是否匹配。然而,Hive 会验证文件格式是否和表结构定义的一致。

2. 通过查询语句向表中插入数据

INSERT OVERWRITE TABLE employees
PARTITION (country = 'US', state = 'OR')
SELECT * FROM staged_employees se
WHERE se.cnty = 'US' AND se.st = 'OR';
  • 这里使用了 OVERWRITE 关键字,因此之前分区中的内容将会被覆盖掉。
  • 这里如果没有使用 OVERWRITE 关键字,或者使用 INTO 关键字替换掉 OVERWRITE 的话,那么 Hive 将会以追加的方式写入数据,而不会覆盖掉之前已经存在的内容(Hive 版本不小于 v0.8.0)。
  • 如果表 staged_employees 非常大,而且用户需要对 65 个州都执行这些语句,那么就意味着需要扫描 staged_employees 表 65 次!Hive 提供了另一种 INSERT 语法,可以只扫描一次输入数据,然后按多种方式进行划分。
FROM staged_employees se
INSERT OVERWRITE TABLE employees
  PARTITION (country = 'US', state = 'OR')
  SELECT * WHERE se.cnty = 'US' AND se.st = 'OR'
INSERT OVERWRITE TABLE employees
  PARTITION (country = 'US', state = 'CA')
  SELECT * WHERE se.cnty = 'US' AND se.st = 'CA'
INSERT OVERWRITE TABLE employees
  PARTITION (country = 'US', state = 'IL')
  SELECT * WHERE se.cnty = 'US' AND se.st = 'IL';
  • 上面的语句是独立进行判断的,不是 IF … THEN … ELSE … 结构。
  • 通过使用这个结构,源表中的某些数据可以被写入目标表的多个分区中,或者不被写入任一个分区中。
  • 如果某条记录是满足某个 SELECT … WHERE … 语句的话,那么这条记录就会被写入到指定的表和分区中。

如果需要创建非常多的分区,那么用户就需要写非常多的 SQL。不过 Hive 提供了一个动态分区功能,其可以基于查询参数推断出需要创建的分区名称。

INSERT OVERWRITE TABLE employees
PARTITION (country, state)
SELECT ..., se.cnty, se.st
FROM staged_employees se;

Hive 根据 SELECT 语句中最后 2 列来确定分区字段。假设表 staged_employees 中有 100 个国家和州的话,执行完上面这个查询后,表 employees 就会有 100 个分区。

动态分区功能默认情况下没有开启。开启后,默认是以 严格 模式执行的,在这种模式下要求至少有一列分区字段是静态的。这有助于阻止因设计错误导致查询产生大量的分区。例如,用户可能错误的使用时间戳作为分区字段,然后导致每秒都对应一个分区。还有一些其他相关属性值用于限制资源利用,如下表所示。

属性名称缺省值描述
hive.exec.dynamic.partitionfalse设置成 true,表示开启动态分区功能。
hive.exec.dynamic.partition.modestrict设置成 nonstrict,表示允许所有分区都是动态的。
hive.exec.max.dynamic.partitions.pernode100一个 mapper 或 reducer 可以创建的最大动态分区个数。如果某个 mapper 或 reducer 尝试创建大于这个值的分区的话,则会抛出一个错误信息。
hive.exec.max.dynamic.partitions+1000一个动态分区创建语句可以创建的最大动态分区个数。如果超过这个值,则会抛出一个错误信息。
hive.exec.max.created.files100000全局可以创建的最大文件个数。有一个 Hadoop 计数器会跟踪记录创建了多少个文件,如果超过这个值,则会抛出一个错误信息。

3. 单个查询语句中创建表并加载数据

用户可以在一个语句中完成创建表,并将查询结果载入这个表。

CREATE TABLE ca_employees
AS SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';
  • 使用这个功能的常见情况是从一个大的宽表中选取部分需要的数据集。
  • 这个功能不能用于外部表。

4. 导出数据

如果数据文件恰好是用户需要的格式,那么只需要简单的拷贝文件夹或者文件就可以了。

hadoop fs -cp source_path target_path

否则,用户可以使用 INSERT … DIRECTORY …

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';
  • 一个或者多个文件将会被写入到 /tmp/ca_employees,具体个数取决于调用的 reducer 个数。
  • 不管在源表中数据实际是怎么存储的,Hive 会将所有的字段序列化成字符串写入到文件中。Hive 使用和 Hive 内部存储的表相同的编码方式来生成输出文件。
  • 和向表中插入数据一样,用户也是可以同时指定多个输出文件夹目录的。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

G皮T

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

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

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

打赏作者

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

抵扣说明:

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

余额充值