假设我正在创建一个表 foo,其列 bar 应该是一个非常大的随机整数。
CREATE TABLE foo (
bar bigint DEFAULT round(((9223372036854775807::bigint)::double precision * random())) NOT NULL,
baz text
);
这是最好的方法吗?谁能评价一下 PostgreSQL 的
random()
函数的质量吗?这里的乘法是否掩盖了熵?
请注意,我确实有良好的硬件熵输入到
/dev/random
。
Postgresql random 基于他们自己的 POSIX erand48 的 可移植实现。它是 48 位域中的线性同余 PRNG。
如果您需要更强大的功能,请查看 pg_crypto 模块的 gen_random_bytes 函数,该函数用于生成加密强熵。
从版本 15.0(2022 年 10 月发布)开始,PostgreSQL 使用
xoroshiro128**
作为其 PRNG 算法,用于在其他 Postgres 函数中生成 random()
的值。 xoroshiro
算法系列于 2018 年推出,截至撰写本文时,仍然相当先进。
关于乘法问题,参考@dbenhur的评论,新算法及其64位输出将为您的方法产生更好的结果,但您仍然存在双精度瓶颈,因此您仍然无法最大化您的263−1 域。
如果您可以放宽对整数列的要求,特别是如果您不需要它作为主键,请考虑使用
double precision
类型列直接保存 random()
值的更简单、更优雅的替代方案。