Php 如何在MySQL中生成唯一的id?
我正在用PHP和MySQL编写一个脚本,我想得到一个 唯一id(由字符串组成:大写和小写 带有数字的字母)如:Php 如何在MySQL中生成唯一的id?,php,sql,mysql,Php,Sql,Mysql,我正在用PHP和MySQL编写一个脚本,我想得到一个 唯一id(由字符串组成:大写和小写 带有数字的字母)如:gHYtUUi5b。 我发现PHP中有很多函数可以生成这样的数字,但我担心如何确保id是唯一的 更新:uuid很长,我的意思是这样的id:(P5Dc)一个11个字母数字字符。我使用uuid()创建一个唯一的值 例如: insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID"); 编程方式可以是:
gHYtUUi5b
。
我发现PHP中有很多函数可以生成这样的数字,但我担心如何确保id是唯一的
更新:uuid很长,我的意思是这样的id:(P5Dc)一个11个字母数字字符。我使用uuid()创建一个唯一的值
例如:
insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID");
编程方式可以是:
- 向字段添加唯一索引
- 在PHP中生成一个随机字符串
- PHP中的循环(同时(!执行插入))
- 生成另一个字符串
- 这可能是肮脏的,但其优点是不可知于DBMS
- 即使您选择使用DBMS特定的唯一ID生成器函数(UUID等) 最佳做法是使用索引确保字段必须是唯一的
- 循环在统计上根本不执行,它只在插入失败时输入
- 使用
我不知道PHP中生成唯一值的过程的来源。如果是库函数,他们应该保证您的值是唯一的。签入文档。你应该一直使用这个功能。例如,如果您使用PHP函数生成唯一值,然后决定使用MySQL函数,则可以生成已经存在的值。在这种情况下,将唯一索引放在列上也是一个好主意。为了唯一性,我要做的是获取Unix时间戳并向其附加一个随机字符串,然后使用它。下面只是作为数字唯一随机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;
您可以使用类似->
$rand=mt_rand(1000099999)的代码添加字符。$randomchar;//假设$radomchar包含char代码> 您也可以考虑使用<代码>密码()/代码>来在您的约束中生成(几乎保证的)唯一ID。 您可能喜欢我们这样做的方式。我想要一个看起来“随机”的可逆唯一代码,这是一个相当常见的问题
- 我们输入一个数字,比如1942李>
- 左键将其填充为字符串:“0000001942”
- 将最后两位数字放在前面:“4200000019”
- 将其转换为一个数字:4200000019
我们现在有一个电话号码,在不同的通话中差别很大,保证不超过1000000000。开始不错
- 将该数字转换为34进制字符串:“2oevc0b”
- 将任何零替换为“y”,将任何零替换为“z”:“2oevcyb”
- 升档:“2OEVCYB”
选择base 34的原因是,我们不必担心0/O和1/l碰撞。现在,您有了一个简短的随机键,可以用来查找长数据库标识符。如何生成唯一ID是一个有用的问题-但您似乎在对何时生成它们做出一个适得其反的假设
我的观点是,您不需要在创建行时生成这些唯一id,因为它们基本上独立于插入的数据
我所做的是预先生成唯一的id供将来使用,这样我就可以享受自己的甜蜜时光,并绝对保证它们是唯一的,并且在插入时不需要进行任何处理
例如,我有一个orders表,其中包含order\u id。该id是在用户输入订单时动态生成的,增量为1、2、3等。用户不需要查看此内部id
然后我有另一个表-unique_id和(order_id,unique_id)。我有一个每天晚上运行的例程,它预先加载这个表,其中包含足够多的唯一id行,足以覆盖未来24小时内可能插入的订单。(如果我在一天内收到10000份订单,我会遇到一个问题——但这将是一个很好的问题!)
这种方法保证了唯一性,并将任何处理负载从insert事务转移到批处理例程,在批处理例程中不会影响用户。crypt()
如建议,将salt存储在某个配置文件中,从1开始salt,如果发现重复,则移动到下一个值2。你可以用2个字符,但这将给你足够的组合盐
<?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";
?>
您可以从openssl\u random\u pseudo\u字节(8)
生成字符串。因此,当使用crypt()
运行时,应该会产生随机的短字符串(11个字符)
从结果中删除salt,如果您在每次随机失败时更改salt,则只有11个字符的随机数足以容纳1亿多个字符。如果您使用版本高于5.7.4的MySQL,您可以使用新添加的函数:
SELECT TO_BASE64(RANDOM_BYTES(16));
这将产生一个随机字符串,如GgwEvafNLWQ3+ockEST00A==
这将生成随机ID:
CREATE TABLE Persons (
ID Integer PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
并将存储过程调用为GenerateUniqueValue('tableName','columnName')。这将每次为您提供一个8位数的唯一字符 要获得唯一且随机的令牌,您只需加密您的主键即可,即:
从您的\u表中选择十六进制(AES\u ENCRYPT(您的\u pk,'your\u password'))作为“令牌”代码>
这已经足够好了,加上它的可逆性,所以您不必将该令牌存储在表中,而是生成它
另一个优点是,一旦您从该令牌解码您的PK,您就不必在您的表上进行繁重的全文搜索,而只需进行简单快速的PK搜索
不过有一个小问题。MySql支持不同的功能,如果更改,将完全改变您的令牌空间,使旧令牌无用
为了克服这个问题,可以在生成令牌之前设置该变量,即:
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;
另一个问题
SELECT CONCAT(CONV(CRC32(@@GLOBAL.block_encryption_mode),10,35),'Z',HEX(AES_ENCRYPT(your_pk,'your_password'))) AS 'token' FROM your_table;
INSERT INTO your_table ( token )
SELECT CONCAT(CONV(CRC32(@@GLOBAL.block_encryption_mode),10,35),'Z',HEX(AES_ENCRYPT(your_pk,'your_password'))) AS 'token'
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = "your_table";
$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;