Почему так много коллизий с функцией MariaDB 10.2 RAND ()? - PullRequest
0 голосов
/ 16 октября 2019

Примечание. Запуск MariaDB 10.2.27 в Windows Server 2012 R2 Standard.

Я хотел создать случайные целые числа для использования в 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) и является основным идентификатором.

С пулом 10 ^ 16 чисел и с учетом парадокса дня рождения я бы ожидал около 50% вероятности столкновения после сгенерированных 10 ^ 8 чисел. Очевидно, что в этом есть некоторая разница, но каждый раз, когда я запускаю цикл вставки, я начинаю видеть столкновения почти сразу, а затем повторяю каждые 2000 или 3000 сгенерированных чисел, иногда чаще. После генерации ~ 50 000 случайных чисел я вижу столкновения каждые несколько сотен чисел.

Думая, что, возможно, мое понимание было совершенно неверным, я настроил свой зацикленный код vb.net, чтобы генерировать случайный код локально, а затем вставил его вMariaDB стол. Я определяю новый System.Random в верхней части процедуры, а затем использую его для генерации случайных чисел:

Dim r As Long = CLng(Math.Floor(rNum.NextDouble() * 9999999999999999)) + 1

Обычно это работает намного лучше, но все же не так хорошо, как ябудет ожидать. Обычно он выполняется около 100 000 итераций, прежде чем происходит столкновение, а затем после этого, по-видимому, возникает одно или два столкновения на 10000 генерируемых случайных событий. Иногда партия из 10000 проходит без каких-либо коллизий.

Итак, почему функция MariaDB RAND () работает так плохо по сравнению с функцией vb.net?

1 Ответ

1 голос
/ 19 октября 2019

Дальнейшие эксперименты с 5.6 RAND показывают, что он хорош только до 30 бит. То есть он имеет только около миллиарда различных значений.

Подать ошибку на bugs.mysql.com и / или MariaDB.

30 битов достаточно для большинства приложений. Из тех приложений, для которых это недостаточно хорошо, большинство людей не заметят его пустоты.

FLOAT имеет 24 бит точности;DOUBLE имеет 53. Поэтому 30 нужно DOUBLE, но не заполняет его.

...