我想知道是否有人知道为表的主键创建唯一的随机整数 id 的好方法。我正在使用MySQL。该值必须是整数。
回应:“因为我想使用该值编码为 Base62,然后将其用于 url 中的 id。如果我自动递增,则用户可能会很明显 url id 是如何生成的。 “
如果安全是您的目标,那么使用 Base62,即使使用“随机”生成的数字也无济于事。
更好的选择是:
AUTO_INCREMENT
如果您愿意接受建议并且可以实现它,请使用 UUID。 MySQL 的
UUID()
函数将返回一个 36 个字符的值,可用于 ID
。
如果您想使用整数,我认为您仍然需要创建一个将在
getRandID()
语句中使用的函数 INSERT
。这个函数需要使用随机+检查现有的id来返回一个以前没有使用过的id。
检查 MySQL 的
RAND()
功能。
如何生成 unique_ids 是一个有用的问题 - 但您似乎对何时生成它们做出了适得其反的假设!
我的观点是,您不需要在创建行时生成这些唯一的 id,因为它们本质上独立于所插入的数据。
我所做的是预先生成唯一的ID以供将来使用,这样我就可以享受自己的甜蜜时光并绝对保证它们是唯一的,并且在插入时无需进行任何处理。
例如,我有一个订单表,其中包含 order_id。当用户输入订单时,此 id 会动态生成,递增 1、2、3 等,直到永远。用户不需要看到这个内部ID。
然后我有另一个表 - unique_ids 和(order_id,unique_id)。我有一个每天晚上运行的例程,它会在该表中预加载足够的 unique_id 行,以覆盖未来 24 小时内可能插入的订单。 (如果我有一天收到 10000 个订单,我就会遇到问题 - 但这将是一个好问题!)
这种方法保证了唯一性,并将任何处理负载从插入事务转移到批处理例程中,而不会影响用户。
您可以为您的表使用
AUTO_INCREMENT
,但为用户提供加密版本:
加密_id:
SELECT HEX(AES_ENCRYPT(id, 'my-private-key'));
id:
SELECT AES_DECRYPT(UNHEX(encrypted_id), 'my-private-key');
这种方法怎么样(
PHP
和MySQL
):
短
number
生成随机
user_id (UNIQUE)
number
为 user_id
看起来很重?继续阅读。
长:
表:
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);
$min
、$max
、0.5
)仅用于解释,没有统计意义。insert_to_table
和 report_this_fact
不是用 PHP 构建的。它们也是数字,只是为了澄清解释目的。我的方式,适用于 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;
}
是的,可以,如果您不想,请不要使用 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)