我正在使用PHP和MySQL编写脚本,我希望得到一个
唯一ID(由字符串组成:大写字母和小字符
带数字的字母):gHYtUUi5b
。
我发现PHP中的许多函数可以生成这样的数字,但我担心如何确保id是唯一的!
UPDATE :uuid很长,我的意思是这样的id:(P5Dc)一个11个字母数字字符。
答案 0 :(得分:52)
我使用UUID()创建一个唯一值。
示例:
insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID");
答案 1 :(得分:20)
您可能喜欢我们这样做的方式。我想要一个看似“随机”的可逆唯一代码 - 一个相当常见的问题。
我们现在有一个号码在通话之间变化很大,保证不到10,000,000,000。这不是一个糟糕的开始。
选择基数34的原因是我们不担心0 / O和1/1碰撞。现在,您有一个短随机密钥,可用于查找LONG数据库标识符。
答案 2 :(得分:13)
程序化方式可以是:
<强> 注意:的强>
答案 3 :(得分:6)
如何生成unique_ids是一个有用的问题 - 但是当你生成它们时,你似乎正在对进行反效果假设!
我的观点是,您在创建行时不需要生成这些唯一ID,因为它们基本上与所插入的数据无关。
我所做的是预先生成唯一ID以供将来使用,这样我就可以享受自己的美好时光并绝对保证它们是独一无二的,并且在插入时无法完成任何处理。
例如,我有一个带有order_id的订单表。当用户输入订单时,会立即生成此ID,永久递增1,2,3等。用户无需查看此内部ID。
然后我有另一个表 - unique_ids with(order_id,unique_id)。我有一个每天晚上运行的例程,它会为此表预加载足够多的unique_id行,以覆盖可能在接下来的24小时内插入的订单。 (如果我在一天内获得10000份订单,我就会遇到问题 - 但这将是一个很好的问题!)
这种方法保证了唯一性,并且可以将任何处理负载从插入事务转移到批处理例程中,而不会影响用户。
答案 4 :(得分:4)
如果您使用版本高于5.7.4的MySQL,则可以使用新添加的RANDOM_BYTES函数:
SELECT TO_BASE64(RANDOM_BYTES(16));
这会产生一个随机字符串,例如GgwEvafNLWQ3+ockEST00A==
。
答案 5 :(得分:3)
我不知道PHP中用于生成唯一值的过程的来源。如果它是库函数,它们应该保证您的值非常独特。签入文档。您应该始终使用此功能。例如,如果您使用PHP函数生成唯一值,然后您决定使用MySQL函数,则可以生成已存在的值。在这种情况下,在列上放置UNIQUE INDEX也是一个好主意。
答案 6 :(得分:1)
对于唯一性,我所做的是使用Unix时间戳并附加一个随机字符串并使用它。
答案 7 :(得分:1)
DELIMITER $$
USE `temp` $$
DROP PROCEDURE IF EXISTS `GenerateUniqueValue`$$
CREATE PROCEDURE `GenerateUniqueValue`(IN tableName VARCHAR(255),IN columnName VARCHAR(255))
BEGIN
DECLARE uniqueValue VARCHAR(8) DEFAULT "";
DECLARE newUniqueValue VARCHAR(8) DEFAULT "";
WHILE LENGTH(uniqueValue) = 0 DO
SELECT CONCAT(SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1)
) INTO @newUniqueValue;
SET @rcount = -1;
SET @query=CONCAT('SELECT COUNT(*) INTO @rcount FROM ',tableName,' WHERE ',columnName,' like ''',newUniqueValue,'''');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
IF @rcount = 0 THEN
SET uniqueValue = @newUniqueValue ;
END IF ;
END WHILE ;
SELECT uniqueValue;
END$$
DELIMITER ;
将存储过程称为GenerateUniqueValue(&#39; tableName&#39;,&#39; columnName&#39;)。这将每次给你一个8位数的独特角色。
答案 8 :(得分:0)
以下仅供参考数字唯一随机ID ...
它可能对你有帮助......
$query=mysql_query("select * from collectors_repair");
$row=mysql_num_rows($query);
$ind=0;
if($row>0)
{
while($rowids=mysql_fetch_array($query))
{
$already_exists[$ind]=$rowids['collector_repair_reportid'];
}
}
else
{
$already_exists[0]="nothing";
}
$break='false';
while($break=='false'){
$rand=mt_rand(10000,999999);
if(array_search($rand,$alredy_exists)===false){
$break='stop';
}else{
}
}
echo "random number is : ".$echo;
你可以使用代码添加char,例如 - &gt; $rand=mt_rand(10000,999999) .$randomchar; // assume $radomchar contains char;
答案 9 :(得分:0)
您也可以考虑使用crypt()
*在您的约束内生成[几乎保证]唯一ID。
答案 10 :(得分:0)
<?php
$hostname_conn = "localhost";
$database_conn = "user_id";
$username_conn = "root";
$password_conn = "";
$conn = mysql_pconnect($hostname_conn, $username_conn, $password_conn) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_select_db($database_conn,$conn);
// run an endless loop
while(1) {
$randomNumber = rand(1, 999999);// generate unique random number
$query = "SELECT * FROM tbl_rand WHERE the_number='".mysql_real_escape_string ($randomNumber)."'"; // check if it exists in database
$res =mysql_query($query,$conn);
$rowCount = mysql_num_rows($res);
// if not found in the db (it is unique), then insert the unique number into data_base and break out of the loop
if($rowCount < 1) {
$con = mysql_connect ("localhost","root");
mysql_select_db("user_id", $con);
$sql = "insert into tbl_rand(the_number) values('".$randomNumber."')";
mysql_query ($sql,$con);
mysql_close ($con);
break;
}
}
echo "inserted unique number into Data_base. use it as ID";
?>
答案 11 :(得分:0)
crypt()
并在一些配置文件中存储盐,从1开始盐,如果你发现重复移动到下一个值2.你可以使用2个字符,但这将为你提供足够的盐组合。 / p>
您可以从openssl_random_pseudo_bytes(8)
生成字符串。因此,当使用crypt()
运行时,这应该给出随机和短字符串(11个字符)。
从结果中删除盐,如果你在每次随机失败时改变盐,那么只有11个字符应该足够随机,超过100万。
答案 12 :(得分:0)
这会生成随机ID:
CREATE TABLE Persons (
ID Integer PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
答案 13 :(得分:0)
要获得唯一且外观随机的令牌,您可以仅加密主密钥,即:
SELECT HEX(AES_ENCRYPT(your_pk,'your_password')) AS 'token' FROM your_table;
这已经足够好,而且它具有可逆性,因此您不必将该令牌存储在表中,而只需生成即可。
另一个优点是,一旦您从该令牌中解码了PK,就不必对表进行大量的全文搜索,而只需简单而快速的PK搜索。
尽管有一个小问题。 MySql支持不同的block encryption modes,如果更改,{{3}}会完全改变您的令牌空间,从而使旧令牌无效...
要克服这一点,可以在生成令牌之前设置该变量,即:
SET block_encryption_mode = 'aes-256-cbc';
但是这有点浪费...解决方案是将加密模式使用的标记附加到令牌:
SELECT CONCAT(CONV(CRC32(@@GLOBAL.block_encryption_mode),10,35),'Z',HEX(AES_ENCRYPT(your_pk,'your_password'))) AS 'token' FROM your_table;
如果您希望将该令牌保留在INSERT
的表中,则可能会出现另一个问题,因为要生成该令牌,您需要知道尚未插入的记录的primary_key ...当然,您可能只是{{ 1}},然后将INSERT
与UPDATE
一起使用-但是,还有一个更好的解决方案:
LAST_INSERT_ID()
此解决方案的最后一个但并非最不重要的优点是,您可以轻松地以php,python,js或您可能使用的任何其他语言来复制它。
答案 14 :(得分:0)
您可以使用Twitter的雪花。
简而言之,它会根据时间,服务器ID和序列来生成唯一ID。它生成一个64位的值,因此它很小并且适合INT64。它还允许正确排序值。
https://developer.twitter.com/en/docs/basics/twitter-ids
总而言之,它允许多台服务器,高度并发,排序值以及所有这些都以64位显示。
这是MySQL的实现
https://github.com/EFTEC/snowflake-mysql
它由一个函数和一个表组成。
答案 15 :(得分:0)
使用它
$info = random_bytes(16);
$info[6] = chr(ord($info[6]) & 0x0f | 0x40);
$info[8] = chr(ord($info[8]) & 0x3f | 0x80);
$result =vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($info), 4));
return $result;