74

我已经安装了 Hadoop、Hive、Hive JDBC。这对我来说运行良好。但我仍然有一个问题。如何使用 Hive 删除或更新单个记录,因为 MySQL 的删除或更新命令在 Hive 中不起作用。

谢谢

hive> delete from student where id=1;
Usage: delete [FILE|JAR|ARCHIVE] <value> [<value>]*
Query returned non-zero code: 1, cause: null
4

15 回答 15

108

从 Hive 版本0.14.0 开始:INSERT...VALUES、UPDATE 和 DELETE 现在可提供完整的 ACID 支持。

插入...值语法:

INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...]

其中 values_row 是: ( value [, value ...] ) 其中一个值为 null 或任何有效的 SQL 文字

更新语法:

UPDATE tablename SET column = value [, column = value ...] [WHERE expression]

删除语法:

DELETE FROM tablename [WHERE expression]

此外,来自 Hive Transactions 文档:

如果要在 ACID 写入(插入、更新、删除)中使用表,则必须在该表上设置表属性“事务”,从 Hive 0.14.0 开始。没有这个值,插入将以旧样式完成;将禁止更新和删除。

Hive DML 参考:
https
: //cwiki.apache.org/confluence/display/Hive/LanguageManual+DML Hive 事务参考:
https ://cwiki.apache.org/confluence/display/Hive/Hive+Transactions

于 2015-03-03T13:44:40.407 回答
74

您不应该将 Hive 视为常规 RDBMS,Hive 更适合对非常大的不可变数据集进行批处理。

以下适用于 Hive 0.14 之前的版本,更高版本请参见ashtonium的回答。

不支持删除或更新特定记录或特定记录集的操作,对我来说,这更多是模式不佳的标志。

以下是您可以在官方文档中找到的内容:

Hadoop is a batch processing system and Hadoop jobs tend to have high latency and
incur substantial overheads in job submission and scheduling. As a result -
latency for Hive queries is generally very high (minutes) even when data sets
involved are very small (say a few hundred megabytes). As a result it cannot be
compared with systems such as Oracle where analyses are conducted on a
significantly smaller amount of data but the analyses proceed much more
iteratively with the response times between iterations being less than a few
minutes. Hive aims to provide acceptable (but not optimal) latency for
interactive data browsing, queries over small data sets or test queries.

Hive is not designed for online transaction processing and does not offer
real-time queries and row level updates. It is best used for batch jobs over
large sets of immutable data (like web logs).

解决此限制的一种方法是使用分区:我不知道您的id对应于什么,但如果您分别获得不同批次的 id,您可以重新设计您的表,使其按 id 分区,然后您将能够轻松删除要删除的 id 的分区。

于 2013-07-23T14:08:27.950 回答
23

是的,说得对。Hive 不支持 UPDATE 选项。但是可以使用以下替代方法来实现结果:

更新 a 中的记录partitioned Hive table

  1. 假定主表由某个键分区。
  2. 将增量数据(要更新的数据)加载到使用与主表相同的键分区的临时表。
  3. 使用如下操作连接两个表(主表和临时表)LEFT OUTER JOIN

    insert overwrite table main_table partition (c,d) select t2.a, t2.b, t2.c,t2.d from staging_table t2 left outer join main_table t1 on t1.a=t2.a;

在上面的示例中,main_table&staging_table使用(c,d)键进行分区。这些表通过 a 连接,结果LEFT OUTER JOIN用于.OVERWRITEmain_table

在操作的情况下也可以使用类似的方法。un-partitioned Hive table UPDATE

于 2014-03-10T05:57:23.017 回答
12

您可以使用一种变通方法从表中删除行,在该变通方法中,您通过操作想要留在表中的数据集覆盖表。

insert overwrite table your_table 
    select * from your_table 
    where id <> 1
;

该解决方法主要用于批量删除易于识别的行。此外,显然这样做会弄乱您的数据,因此建议备份表并在计划“删除”规则时小心谨慎。

于 2014-09-30T10:08:34.863 回答
7

安装和配置 Hive 后,创建简单的表:

hive>create table testTable(id int,name string)row format delimited fields terminated by ',';

然后,尝试在测试表中插入几行。

hive>insert into table testTable values (1,'row1'),(2,'row2');

现在尝试删除记录,您刚刚插入表中。

hive>delete from testTable where id = 1;

错误!失败:SemanticException [错误 10294]:尝试使用不支持这些操作的事务管理器进行更新或删除。

默认情况下,事务配置为关闭。据说转换管理器中使用的删除操作不支持更新。要支持更新/删除,您必须更改以下配置。

cd  $HIVE_HOME
vi conf/hive-site.xml

将以下属性添加到文件

<property>
  <name>hive.support.concurrency</name>
  <value>true</value>
 </property>
 <property>
  <name>hive.enforce.bucketing</name>
  <value>true</value>
 </property>
 <property>
  <name>hive.exec.dynamic.partition.mode</name>
  <value>nonstrict</value>
 </property>
 <property>
  <name>hive.txn.manager</name>
  <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
 </property>
 <property>
  <name>hive.compactor.initiator.on</name>
  <value>true</value>
 </property>
 <property>
  <name>hive.compactor.worker.threads</name>
  <value>2</value>
 </property>

重新启动服务,然后再次尝试删除命令:

错误!

失败:LockException [错误 10280]:与元存储通信时出错。

元存储有问题。为了使用插入/更新/删除操作,您需要更改 conf/hive-site.xml 中的以下配置,因为该功能目前正在开发中。

<property>
  <name>hive.in.test</name>
  <value>true</value>
 </property>

重新启动服务,然后再次删除命令:

hive>delete from testTable where id = 1;

错误!

失败:SemanticException [错误 10297]:尝试对不使用 AcidOutputFormat 或未分桶的表 default.testTable 进行更新或删除。

此第一个版本仅支持 ORC 文件格式。该功能的构建使得任何存储格式都可以使用事务,这些格式可以确定更新或删除如何应用于基本记录(基本上,具有显式或隐式行 ID),但到目前为止,集成工作只完成了兽人。

必须对表进行分桶才能使用这些功能。同一系统中不使用事务和 ACID 的表不需要分桶。

请参阅下面使用 ORCFileformat、启用存储桶和 ('transactional'='true') 的构建表示例。

hive>create table testTableNew(id int ,name string ) clustered by (id) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');

插入 :

hive>insert into table testTableNew values (1,'row1'),(2,'row2'),(3,'row3');

更新 :

hive>update testTableNew set name = 'updateRow2' where id = 2;

删除 :

hive>delete from testTableNew where id = 1;

测试 :

hive>select * from testTableNew ;
于 2019-04-07T19:27:09.937 回答
4

为 INSERT、UPDATE、DELETE 设置的配置值 除了上面列出的新参数之外,还需要设置一些现有参数以支持 INSERT ... VALUES、UPDATE 和 DELETE。

配置键 必须设置为

hive.support.concurrency true (default is false) hive.enforce.bucketing true (default is false) (Not required as of Hive 2.0) hive.exec.dynamic.partition.mode nonstrict (default is strict)

为压缩设置的配置值

如果系统中的数据不属于 Hive 用户(即运行 Hive 元存储的用户),则 Hive 需要以拥有数据的用户身份运行才能执行压缩。如果您已经将 HiveServer2 设置为模拟用户,那么唯一要做的额外工作是确保 Hive 有权模拟来自运行 Hive 元存储的主机的用户。这是通过将主机名添加到 Hadoop 的 core-site.xml 文件中的 hadoop.proxyuser.hive.hosts 来完成的。如果您尚未执行此操作,则需要将 Hive 配置为代理用户。这需要您为运行 Hive 元存储的用户设置 keytab,并将 hadoop.proxyuser.hive.hosts 和 hadoop.proxyuser.hive.groups 添加到 Hadoop 的 core-site.xml 文件。

UPDATE 语句有以下限制:

WHERE 子句中的表达式必须是 Hive SELECT 子句支持的表达式。

无法更新分区和存储桶列。

UPDATE 语句会自动禁用查询向量化。但是,仍然可以使用矢量化查询更新的表。

SET 语句的右侧不允许有子查询。

以下示例演示了此语句的正确用法:

UPDATE students SET name = null WHERE gpa <= 1.0;

删除语句

使用 DELETE 语句删除已写入 Apache Hive 的数据。

DELETE FROM tablename [WHERE expression];

DELETE 语句具有以下限制:对于 DELETE 操作,查询向量化会自动禁用。但是,仍然可以使用矢量化查询已删除数据的表。

以下示例演示了此语句的正确用法:

DELETE FROM students WHERE gpa <= 1,0;

于 2016-12-28T09:54:33.173 回答
3

CLI 告诉你你的错误在哪里:delete WHAT? from student......

删除:如何从 Hadoop-Hive 中删除/截断表?

更新:更新,Hive 中的 SET 选项

于 2013-07-23T13:14:03.717 回答
3

如果您想删除所有记录,那么作为一种解决方法,将一个空文件以 OVERWRITE 模式加载到表中

hive> LOAD DATA LOCAL INPATH '/root/hadoop/textfiles/empty.txt' OVERWRITE INTO TABLE employee;
Loading data to table default.employee
Table default.employee stats: [numFiles=1, numRows=0, totalSize=0, rawDataSize=0]
OK
Time taken: 0.19 seconds

hive> SELECT * FROM employee;
OK
Time taken: 0.052 seconds
于 2015-08-25T12:53:40.643 回答
2

即将发布的 Hive 版本将允许基于 SET 的更新/删除处理,这在尝试对“一堆”行执行 CRUD 操作而不是一次处理一行时至关重要。

在此期间,我尝试了此处记录的基于动态分区的方法http://linkd.in/1Fq3wdb

请看看它是否适合您的需要。

于 2015-04-09T03:59:34.837 回答
1

UPDATE或者DELETEHive 中不允许记录,但INSERT INTO可以接受。
Hadoop的片段:权威指南(第 3 版)

更新、事务和索引是传统数据库的支柱。然而,直到最近,这些功能还没有被认为是 Hive 功能集的一部分。这是因为 Hive 是为使用 MapReduce 对 HDFS 数据进行操作而构建的,其中全表扫描是常态,并且通过将数据转换为新表来实现表更新。对于在大部分数据集上运行的数据仓库应用程序,这很有效。

Hive 不支持更新(或删除),但它支持 INSERT INTO,因此可以向现有表添加新行。

于 2013-12-12T09:35:41.920 回答
1

为了满足您当前的需求,您需要触发以下查询

> insert overwrite table student 
> select *from student 
> where id <> 1;

这将删除当前表并创建具有相同名称的新表,除了要排除/删除的行之外的所有行

我在 Hive 1.2.1 上试过这个

于 2016-10-25T06:40:16.507 回答
1

设置几个属性以使 Hive 表支持 ACID 属性并支持 SQL 中的 UPDATE 、INSERT 和 DELETE

在 Hive 中创建 ACID 表的条件。1. 表应该存储为 ORC 文件。目前只有 ORC 格式可以支持 ACID 属性 2. 表必须分桶

要设置以创建 ACID 表的属性:

set hive.support.concurrency =true;
set hive.enforce.bucketing =true;
set hive.exec.dynamic.partition.mode =nonstrict
set hive.compactor.initiator.on = true;
set hive.compactor.worker.threads= 1;
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;

在 hive.site.xml 中将属性 hive.in.test 设置为 true

设置所有这些属性后,应使用 tblproperty 'transactional' ='true' 创建表。该表应该被存储并保存为兽人

CREATE TABLE table_name (col1 int,col2 string, col3 int) CLUSTERED BY col1 INTO 4 
BUCKETS STORED AS orc tblproperties('transactional' ='true');

现在 Hive 表可以支持 UPDATE 和 DELETE 查询

于 2020-05-25T04:55:00.623 回答
0

最近我想解决一个类似的问题,Apache Hive、Hadoop 不支持更新/删除操作。所以 ?所以你有两种方法:

  1. 使用备份表:将整个表保存在 backup_table 中,然后截断您的输入表,然后只重写您想要维护的数据。
  2. 使用Uber Hudi:它是 Uber 创建的一个框架,用于解决 HDFS 限制,包括删除和更新。您可以在此链接中查看: https ://eng.uber.com/hoodie/

第 1 点的示例:

Create table bck_table like input_table;
Insert overwrite table bck_table 
    select * from input_table;
Truncate table input_table;
Insert overwrite table input_table
    select * from bck_table where id <> 1;

注意:如果 input_table 是外部表,您必须遵循以下链接: How to truncate a partitioned external table in hive?

于 2019-04-03T10:37:17.983 回答
0

好消息,现在可以使用 Kudu 在 Hive/Impala 上插入更新和删除。

您需要使用 IMPALA/kudu 来维护表并执行插入/更新/删除记录。可以在此处找到带有示例的详细信息: insert-update-delete-on-hadoop

如果你很兴奋,请分享这个消息。

-MIK

于 2017-02-08T09:21:34.630 回答
0

最近在 Hive 版本 0.14 中添加了删除 只能在支持 ACID 的表上执行删除 下面是来自 Apache 的链接。

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML#LanguageManualDML-Delete

于 2016-05-29T06:23:35.477 回答