我一直在尝试为每个表格行生成唯一的id(30多亿行)。
- 显然,使用顺序号码不起作用,因为Hadoop是并行的。
- 内置的UDFs rand() 和 hash(rand(),unixtime()) 似乎会产生冲突。
必须有一种简单的方法来生成行id,我想知道是否有人有解决方案。
- 我的下一步就是创建一个Java MapReduce任务,使用安全随机数+主机IP+当前时间作为种子来生成真正的哈希字符串。但在这之前,我想问问这里是否有解决方案 ;)
我一直在尝试为每个表格行生成唯一的id(30多亿行)。
必须有一种简单的方法来生成行id,我想知道是否有人有解决方案。
reflect("java.util.UUID", "randomUUID")
更新(2019)
长期以来,在 Hive 中获得唯一值的最佳选择是 UUID。从 Hive 4.0 开始,Hive 提供了一个 surrogate key UDF,您可以使用它来生成唯一值,这将比 UUID 字符串具有更高的性能。文档仍然有点简略,但这里有一个例子:
create table customer (
id bigint default surrogate_key(),
name string,
city string,
primary key (id) disable novalidate
);
如果想让Hive为您生成ID,请在插入语句中使用列列表,不要提及代理键列:
-- staging_table would have two string columns.
insert into customer (name, city) select * from staging_table;
不确定这是否有帮助,但让我们看看...
考虑本地MapReduce类比:假设您的输入数据集基于文本,那么对于每行,输入Mapper的键(因此唯一ID)将是文件名加上其字节偏移量。
当您将数据加载到Hive中时,如果可以创建一个额外的“列”来保存此信息,则可以免费获得行ID。它在语义上没有意义,但您提到的方法也是如此。
除了jtravaglini提供的答案,自从0.8.0版本以来,Hive内置了两个虚拟列可用于生成唯一标识符:
INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE
使用如下:
select
concat(INPUT__FILE__NAME, ':', BLOCK__OFFSET__INSIDE__FILE) as rowkey,
...
;
...
OK
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:0
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:57
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:114
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:171
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:228
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:285
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:342
...
或者你可以使用MD5或类似的方式进行匿名处理,这里是一个MD5 UDF的链接:https://gist.github.com/dataminelab/1050002
(请注意函数类名应为initcap 'Md5')
select
Md5(concat(INPUT__FILE__NAME, ':', BLOCK__OFFSET__INSIDE__FILE)) as rowkey,
...
INPUT__FILE__NAME
BLOCK__OFFSET__INSIDE__FILE
- bcollinsreflect("java.util.UUID", "randomUUID")
反射 "java.util.UUID" 类的 "randomUUID" 方法。我不能投票支持其他答案。我需要一个纯二进制版本,所以我使用了以下代码:
unhex(regexp_replace(reflect('java.util.UUID','randomUUID'), '-', ''))