我想有一个持久化的列,它将根据varchar
表中的关键列之一随机分组 32 个组的数据。我的想法是:
SELECT ABS(CAST(HASHBYTES('MD5',[keyColumnFromTable]) AS bigint) % 31)
问题:
CHECKSUM
除了(不同的值不同COLLATE
)和自己的功能之外,还有什么更好的方法吗?- 如果我会使用会有什么不同
SELECT CAST(HASHBYTES('MD5',[keyColumnFromTable]) AS tinyint) % 31
?我正在阅读它CAST
正在tinyint
考虑最后一个字节的数据。对随机性有影响吗?
一种替代方法是使用序列来执行循环分配。定义序列的最小值和最大值以匹配必要的桶数。就像是
保存组号的持久列可以具有默认值
..next value for group_sequence
.其随机性将取决于新行的到达顺序。例如,如果您有 32 个输入流,并且它们一个接一个地发送行,那么显然每个流的行最终将归为一组。如果数据以批次的形式到达,则该批次将均匀分布在所有组中,或取几行。我不能说这对您的计算质量是否重要。
关于转换为 tinyint 的问题,我没有数学答案,只是观察。由于 MD5 哈希返回 16 字节转换为 bigint 已经产生截断。为什么转换为 tinyint 会更有问题?您可以直接对 HASHBYTES 的结果执行模计算,这将执行隐式转换为 4 字节 int。
另请注意,强制转换散列可能会产生负整数。与其他组相比,在计算模数后取绝对值将给出零组中大约一半的行数。由于 tinyint 不能为负数,至少可以避免这种情况。