注意:在Windows Server 2012 R2 Standard上运行MariaDB 10.2.27。
我想生成用于MariaDB的随机整数,因此我一直在尝试使用MariaDB RAND()函数。我的期望和理解都偏离了基础(绝对有可能!),或者MariaDB RAND()函数不是非常随机的。
使用BIGINT(20)专栏中,我想生成随机整数最大长度为16位,所以我用这个SQL: FLOOR(RAND()*9999999999999999)+1)。我在循环中使用的确切SQL是:
FLOOR(RAND()*9999999999999999)+1)
INSERT INTO rnd_test VALUES (FLOOR(RAND()*9999999999999999)+1);
表rnd_test具有单个列,该列是BIGINT(20)并且是主要ID。
在有10 ^ 16个数字的池中,考虑到生日悖论,我希望在生成10 ^ 8个数字后发生碰撞的几率约为50%。显然这会有一些差异,但是每次我运行插入循环时,我几乎都立即看到冲突,然后每2000或3000个生成的数字(有时更频繁)重复一次。生成约50,000个随机数后,我发现每隔几百个数字就会发生冲突。
考虑到我的理解可能是完全错误的,我调整了循环vb.net代码以在本地生成随机数,然后将其插入到MariaDB表中。我在例程的顶部定义了一个新的System.Random,然后使用它来生成随机数:
Dim r As Long = CLng(Math.Floor(rNum.NextDouble() * 9999999999999999)) + 1
通常,此方法效果更好,但仍不如我预期的好。在发生碰撞之前,它通常会运行约100,000次迭代,然后在此之后,每生成10,000个随机变量,似乎就会发生一两次碰撞。有时,将有10,000个批次完全没有碰撞。
那么,为什么与vb.net函数相比,MariaDB RAND()函数的性能如此差?
5.6的RAND的进一步实验表明,只有30位是好的。也就是说,它只有大约十亿个不同的值。
使用bugs.mysql.com和/或MariaDB提交错误。
30位足以满足大多数应用的需求。在那些它还不够好的应用程序中,大多数人不会注意到它的缺点。
FLOAT具有24位精度;DOUBLE有53。因此有30个需求DOUBLE,但无法满足需求。
FLOAT
DOUBLE