如何为表的主键创建唯一的随机整数ID?

问题描述 投票:0回答:9

我想知道是否有人知道为表的主键创建唯一的随机整数 id 的好方法。我正在使用MySQL。该值必须是整数。

mysql sql primary-key uniqueidentifier
9个回答
14
投票

回应:“因为我想使用该值编码为 Base62,然后将其用于 url 中的 id。如果我自动递增,则用户可能会很明显 url id 是如何生成的。 “

如果安全是您的目标,那么使用 Base62,即使使用“随机”生成的数字也无济于事。

更好的选择是:

  • 不要重新发明轮子——使用
    AUTO_INCREMENT
  • 然后使用加密哈希函数 + 随机生成的字符串(隐藏在该特定 url 的数据库中)来生成最终的“该 url 的唯一 id”

11
投票

如果您愿意接受建议并且可以实现它,请使用 UUID。 MySQL 的

UUID()
函数将返回一个 36 个字符的值,可用于
ID

如果您想使用整数,我认为您仍然需要创建一个将在

getRandID()
语句中使用的函数
INSERT
。这个函数需要使用随机+检查现有的id来返回一个以前没有使用过的id。

检查 MySQL 的

RAND()
功能。


7
投票

如何生成 unique_ids 是一个有用的问题 - 但您似乎对何时生成它们做出了适得其反的假设!

我的观点是,您不需要在创建行时生成这些唯一的 id,因为它们本质上独立于所插入的数据。

我所做的是预先生成唯一的ID以供将来使用,这样我就可以享受自己的甜蜜时光并绝对保证它们是唯一的,并且在插入时无需进行任何处理。

例如,我有一个订单表,其中包含 order_id。当用户输入订单时,此 id 会动态生成,递增 1、2、3 等,直到永远。用户不需要看到这个内部ID。

然后我有另一个表 - unique_ids 和(order_id,unique_id)。我有一个每天晚上运行的例程,它会在该表中预加载足够的 unique_id 行,以覆盖未来 24 小时内可能插入的订单。 (如果我有一天收到 10000 个订单,我就会遇到问题 - 但这将是一个好问题!)

这种方法保证了唯一性,并将任何处理负载从插入事务转移到批处理例程中,而不会影响用户。


3
投票

您可以为您的表使用

AUTO_INCREMENT
,但为用户提供加密版本:

加密_id:

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

id:

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


2
投票

这种方法怎么样(

PHP
MySQL
):


  1. number
     生成随机 
    user_id (UNIQUE)
  2. 插入生成的
    number
    user_id
  3. 的行
  4. 如果插入的行数等于0,则转到第1点

看起来很重?继续阅读。


表:

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
投票

我的方式,适用于 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
投票

AUTO_INCREMENT
将是您最好的选择。

这里有一些例子。

如果需要,您可以调整增量值的开始位置(默认为 1)。


0
投票

有一个

AUTO_INCREMENT
功能。我会用那个。

请参阅此处更多示例。


0
投票

是的,可以,如果您不想,请不要使用 AUTO_INCRMENT。

试试这个:

CREATE TABLE `demotable` (
    `MyUUID` VARCHAR(64) NOT NULL DEFAULT uuid() COLLATE 'utf8_general_ci',
    `MyValue` BIGINT(20) NULL DEFAULT NULL,
    PRIMARY KEY (`MyUUID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

它创建一个主键 MyUUID,其默认值是唯一的表达式。

看看你自己,当你添加像他这样的值时,它会创建一个新的uuid:

INSERT INTO demotable(MyValue) VALUES(1)
© www.soinside.com 2019 - 2024. All rights reserved.