Как создать уникальный случайный целочисленный идентификатор для первичного ключа для таблицы? - PullRequest
9 голосов
/ 19 ноября 2010

Мне было интересно, знает ли кто-нибудь хороший способ создать уникальный случайный целочисленный идентификатор для первичного ключа для таблицы. Я использую MySQL. Значение должно быть целым числом.

Ответы [ 8 ]

13 голосов
/ 19 ноября 2010

В ответ на: "Потому что я хочу использовать это значение для кодирования в Base62, а затем использовать его для идентификатора в URL-адресе. Пользователь, как генерируется URL-адрес. "

Если ваша цель - безопасность, то использование Base62, даже с "случайно" сгенерированным числом, не поможет.

Лучший вариант:

  • Не изобретать велосипед - используйте AUTO_INCREMENT
  • Затем используйте криптографическую хеш-функцию + случайно сгенерированную строку (скрытую в БД для этого конкретного URL), чтобы сгенерировать окончательный «уникальный идентификатор для этого URL»
9 голосов
/ 19 ноября 2010

Если вы открыты для предложений и можете их реализовать, используйте UUID.Функция MySQL UUID() вернет значение 36 символов, которое можно использовать для ID.

Если вы хотите использовать целое число, я думаю, вам нужно создать функцию getRandID(), которую вы будете использоватьв заявлении INSERT.Эта функция должна использовать случайный + проверка существующих идентификаторов, чтобы вернуть тот, который раньше не использовался.

Проверка RAND() функции для MySQL.

7 голосов
/ 05 августа 2011

Как вы генерируете unique_ids - это полезный вопрос, но вы, кажется, делаете контрпродуктивное предположение о , когда вы генерируете их!

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

Что я делаю, это предварительно генерирую уникальные идентификаторы для будущего использования, таким образом, я могу взять свой собственный сладкийвремя и абсолютная гарантия, что они уникальны, и во время вставки обработка не производится.

Например, у меня есть таблица заказов с order_id.Этот идентификатор генерируется на лету, когда пользователь вводит заказ, постепенно 1,2,3 и т. Д. Навсегда.Пользователю не нужно видеть этот внутренний идентификатор.

Тогда у меня есть другая таблица - unique_ids с (order_id, unique_id).У меня есть подпрограмма, которая запускается каждую ночь, которая предварительно загружает эту таблицу с достаточным количеством строк unique_id, чтобы более чем покрывать заказы, которые могут быть вставлены в следующие 24 часа.(Если я когда-нибудь получу 10000 заказов за один день, у меня возникнет проблема - но это было бы хорошей проблемой!)

Этот подход гарантирует уникальность и устраняет любую нагрузку обработки от транзакции вставки допакетная процедура, где она не влияет на пользователя.

2 голосов
/ 29 июля 2013

Как насчет этого подхода (PHP и MySQL):


Short

  1. Генерация случайных number для user_id (UNIQUE)
  2. Вставить строку с сгенерированным number как user_id
  3. Если число вставленных строк равно 0, переходите к точке 1

выглядит тяжелым? Продолжайте читать.


Long

Таблица:

users (user_id int UNIQUE)

Код:

<?php
// values stored in configuration
$min = 1;
$max = 1000000;

$numberOfLoops = 0;
do {
    $randomNumber = rand($min, $max);

    // the very insert
    $insertedRows = insert_to_table(
        'INSERT INTO foo_table (user_id) VALUES (:number)', 
        array(
            ':number' => $randomNumber
        ));

    $numberOfLoops++;

    // the magic
    if (!isset($reported) && $numberOfLoops / 10 > 0.5) {
        /**
         * We can assume that at least 50% of numbers
         * are already in use, so increment values of
         * $min and $max in configuration.
         */
        report_this_fact();
        $reported = true;
} while ($insertedRows < 1);

  1. Все значения ($min, $max, 0.5) приведены только для пояснения и не имеют статистического значения.
  2. Функции insert_to_table и report_this_fact не встроены в PHP. Они также являются числами только для пояснения целей объяснения.
0 голосов
/ 18 июля 2017

Вы можете использовать AUTO_INCREMENT для своей таблицы, но предоставить пользователям зашифрованную версию:

encrypted_id: SELECT HEX(AES_ENCRYPT(id, 'my-private-key'));

id: SELECT AES_DECRYPT(UNHEX(encrypted_id), 'my-private-key');

0 голосов
/ 27 июня 2014

по-моему, как для 32-битной, так и для 64-битной платформы. результат 64 бит

function hexstr2decstr($hexstr){
    $bigint = gmp_init($hexstr, 16);
    $bigint_string = gmp_strval($bigint);
    return $bigint_string;
}

function generate_64bitid(){
    return substr(md5(uniqid(rand(), true)), 16, 16);
}

function dbGetUniqueXXXId(){
    for($i = 0; $i < 10; $i++){
        $decstr = hexstr2decstr(generate_64bitid());

        //check duplicate for mysql.tablexxx
        if($dup == false){
            return $decstr;
        }
    }
    return false;
}
0 голосов
/ 19 ноября 2010

AUTO_INCREMENT будет вашим лучшим выбором для этого.

Здесь - несколько примеров.

Если вам нужно, вы можете настроить, где начинается значение приращения (по умолчанию это 1).

0 голосов
/ 19 ноября 2010

Есть функция AUTO_INCREMENT. Я бы использовал это.

См. здесь больше примеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...