如何向查询结果中添加一个整数唯一id-\uuuuu有效\uuuuuu?

41ik7eoe  于 2021-05-29  发布在  Hadoop
关注(0)|答案(4)|浏览(259)

如果有人问, select * from ... (这可能是ctas声明的一部分)
我们的目标是增加一列, ID ,在哪里 ID 是唯一整数。

select ... as ID,* from ...

附笔 ID 不必是连续的(可能有间隙)
id可以是任意的(不必表示结果集中的特定顺序)
行号从逻辑上解决了这个问题-

select row_number() over () as ID,* from ...

问题是,至少目前,全局行数(没有分区依据)是使用单个缩减器(hive)/任务(spark)实现的。

oaxa6hgo

oaxa6hgo1#

检查一下这个全局唯一的id服务https://github.com/spinaki/distributed-unique-id 它也有一个码头形象,你可以快速测试。

flmtquvp

flmtquvp2#

如果您使用的是sparksql,那么最好使用内置函数
单调递增的
在单独的列中生成唯一的随机id。正如你所说,你不需要它是连续的,所以这应该满足你的理想要求。

34gzjxbg

34gzjxbg3#

检查manoj kumar的溶液:https://github.com/manojkumarvohra/hive-hilo
创建一个有状态的udf,它维护一个hi/lo计数器来递增序列。
在zookeeper中,hi值保持为distribute atomic long。
hi值每n lo(默认200)次迭代递增并获取一次。
udf支持单个字符串参数,该参数是用于在zookeeper中维护znodes的序列名称。
用法:

FunctionName( sequenceName, lowvalue[optional], seedvalue[optional])
gzszwxb4

gzszwxb44#

Hive

set mapred.reduce.tasks=1000;
set hivevar:buckets=10000;
``` `hivevar:buckets` 相对减速机的数量应该足够高( `mapred.reduce.tasks` ),因此行将均匀地分布在两个行之间。

select 1 + x + (row_number() over (partition by x) - 1) * ${hivevar:buckets} as id
,t.*

from (select t.*
,abs(hash(rand())) % ${hivevar:buckets} as x

    from    t
    ) t
Sparksql

select 1 + x + (row_number() over (partition by x) - 1) * 10000 as id
,t.*

from (select t.*
,abs(hash(rand())) % 10000 as x

    from    t
    ) t
对于hive和spark sql
这个 `rand()` 用于生成良好的分布。
如果您的查询中已经有一列/列组合具有良好的分布(可能是唯一的,而不是必须的),您可以使用它来代替,例如-

select 1 + (abs(hash(col1,col)) % 10000)
+ (row_number() over (partition by abs(hash(col1,col)) % 10000) - 1) * 10000 as id
,t.*

from t

相关问题