使用 HASH 作为 Snowflake 中的替代维度键?

Using HASH as an alternate dimension key in Snowflake?

(代表 Snowflake 客户提交)

.......................

我想创建一个具有 JSON 属性的维度。

我正在考虑使用 HASH 来唯一标识我的行,包括 JSON 列。

我希望在该维度中有几百万行。

Snowflake 文档 (https://docs.snowflake.net/manuals/sql-reference/functions/hash.html) 说 HASH 可能会产生 40 亿行或更多行的重复...并警告不要将 HASH 用作键...

当只有几百万行成员时,使用 HASH 值作为键是否是一种合理的方法?

.......................

有什么想法、替代建议或可能的解决方法吗?谢谢。

这是个有趣的问题。

假设 散列确实非常随机,计算碰撞概率实际上是birthday problem 的扩展。我们可以将概率近似为

p(碰撞) ≈ 1 - e^(-(n^2)/2d))

其中 n 是值的数量,d 是域的大小。将 2^32(40 亿)作为 n 代入,将 2^64 作为 d 代入,我们得到 p ≈ .39,因此发生碰撞的可能性非常高。

但是如果n只有几百万,这个概率就低很多了。例如,对于 n = 10,000,000,我们得到 p ≈ .0000027。这听起来很安全,但显然存在一些风险。这假设哈希值是完美的,所以你可能应该稍微提高这个概率。

您可以尝试更长、更标准的散列,例如 Snowflake supports 的 SHA-2。总会有一些碰撞的风险,但如果你使散列足够长,它就会变得非常小——这就是你对散列的全部期望。

不过,一个更好的散列替代方法可能是将 JSON 放在单独的 table 中,并使用 autoincrement 为每条记录分配一个真正的唯一标识符。然后您将使用此密钥加入。如果你做对了,它应该总是有效的,我希望 join perf 也会更好。