首页 > 解决方案 > 为什么与 MariaDB 10.2 RAND() 函数发生如此多的冲突?

问题描述

注意:在 Windows Server 2012 R2 Standard 上运行 MariaDB 10.2.27。

我想生成用于 MariaDB 的随机整数,所以我一直在尝试 MariaDB RAND() 函数。要么我的期望和理解偏离了基础(绝对有可能!),要么 MariaDB RAND() 函数不是很随机。

使用 BIGINT(20) 列,我想生成长度不超过 16 位的随机整数,所以我使用了这个 SQL FLOOR(RAND()*9999999999999999)+1):。我在循环中使用的确切 SQL 是:

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() 函数的性能如此差?

标签: mysqlsqlrandommariadb

解决方案


对 5.6 的 RAND 的进一步实验表明,它只适用于 30 位。也就是说,它只有大约十亿个不同的值。

使用 bugs.mysql.com 和/或 MariaDB 提交错误。

30 位对于大多数应用程序来说已经足够了。在那些它不够好的应用程序中,大多数人不会注意到它的懦弱。

FLOAT具有 24 位精度;DOUBLE有 53 个。所以需要 30 个DOUBLE,但没有填满。


推荐阅读