我在 Hive 中有一个用户表,形式如下:
User:
Id String,
Name String,
Col1 String,
UpdateTimestamp Timestamp
我正在从具有以下格式的文件中在此表中插入数据:
I/U、记录写入文件时的时间戳、Id、名称、Col1、UpdateTimestamp
例如,插入一个 ID 为 1 的用户:
I,2019-08-21 14:18:41.002947,1,Bob,stuff,123456
并为 ID 为 1 的同一用户更新 col1:
U,2019-08-21 14:18:45.000000,1,,updatedstuff,123457
未更新的列返回为空。
现在,在 hive 中使用 load in path 在临时表中很容易进行简单的插入,然后忽略 stage 表中的前两个字段。
但是,我将如何处理更新语句?因此,我在 hive 中的最后一行如下所示:
1,Bob,updatedstuff,123457
我想在临时表中插入所有行,然后执行某种合并查询。有任何想法吗?
通常,使用合并语句,您的“文件”在 ID 上仍然是唯一的,并且合并语句将确定是否需要将其作为新记录插入,或更新该记录中的值。
但是,如果文件是不可协商的并且始终具有 I/U 格式,则您可以将过程分为两个步骤,即插入,然后是更新,如您所建议的。
为了在 Hive 中执行更新,您需要将 users 表存储为 ORC 并在集群上启用 ACID。对于我的示例,我将使用集群键和事务表属性创建用户表:
create table test.orc_acid_example_users
(
id int
,name string
,col1 string
,updatetimestamp timestamp
)
clustered by (id) into 5 buckets
stored as ORC
tblproperties('transactional'='true');
在插入语句之后,您的 Bob 记录会在col1
以下内容中显示“东西”
至于更新 - 您可以使用更新或合并语句来解决这些问题。我认为这里的关键是null
价值观。如果文件中的临时表具有null
值,则保留原始名称或 col1 或其他名称很重要。这是一个合并临时表字段的合并示例。基本上,如果暂存表中有一个值,则采用该值,否则回退到原始值。
merge into test.orc_acid_example_users as t
using test.orc_acid_example_staging as s
on t.id = s.id
and s.type = 'U'
when matched
then update set name = coalesce(s.name,t.name), col1 = coalesce(s.col1, t.col1)
快速免责声明 - 如果您在临时表中有多个 Bob 的更新,事情会变得一团糟。在执行更新/合并之前,您需要有一个预处理步骤来获取所有更新的最新非空值。Hive 并不是一个真正完整的事务性数据库 - 源最好在有更新时发送完整的用户记录,而不仅仅是更改的字段。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句