2011-03-31 132 views
1

我正在开发一个mysql数据库。while循环mysql的数据库与PHP?

我“需要”每个用户的唯一ID,但它不能自动递增!它不是自动增量至关重要。

因此,当用户注册我的网站时,我正在考虑在我的mysql表中插入一个类似mt_rand(5000,1000000)的随机数。这是我卡住的地方?!

id是我的mysql表中每个用户特有的唯一键,因为我不能100%保证为用户id插入mt_rand(5000,1000000)不会与其他用户的id不一致。

有没有一种方法可以使用mt_rand(5000,1000000)并扫描mysql数据库,如果它返回true,表明它是唯一的,那么在返回false时插入它作为用户的新ID(已经有人有该id)生成一个新的id,直到它变得唯一,然后将其插入到mysql数据库。

我知道这是可能的我已经看过很多次了,我尝试过while循环和各种各样的,所以这个地方是我的最后一招。

谢谢

+3

使用http://php.net/manual/en/function.uniqid.php – m4tt1mus 2011-04-01 00:02:47

+0

你能解释一下什么是有自动递增的数字问题? – staticsan 2011-04-01 00:16:47

+0

“我”需要“每个用户都有一个唯一的ID,但它不能自动递增!” 你正在解决一些问题。你不会得到一个适当的解决方案。 – tetris 2011-04-01 00:39:08

回答

4

你最好不要使用这样的:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_uuid

或使用本:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

但是,如果你真的想你说的话,你可以这样做:

$x; 
do { 
$x = random_number(); 
"SELECT count(*) FROM table WHERE id = $x" 
} while (count != 0); 
// $x is now a value that's not in the db 
+0

然后,只需使用$ x作为id,执行简单更新以及所有其他$ _POST变量?你能解释一下它的方法,检查它不在数据库中,我没有看到这个方法,也不明白它。谢谢。 – PHP 2011-04-01 00:13:33

+1

UUID是答案(可以使用MySQL或PHP库创建)。随机数的方法开始是一个坏主意,但随着您添加记录它变得更糟,并且您的碰撞机会增加。不做auto_increment的一点是避免数据库争用,如果你开始必须为每个INSERT执行2,4或20个SELECTS,那就很糟糕。 – joelhardi 2011-04-01 00:15:15

+0

如果你不能有自动编号,并且guid不能保证是唯一的,这就是我要做的。无论哪种方式,我都会让数据库处理它。回程减少,并确定是否有重复。 – xecaps12 2011-04-01 00:17:18

0

您可以使用guid。当你不能使用自动编号时,这就是我所看到的。

http://php.net/manual/en/function.com-create-guid.php

+0

仍然不能保证在db中是唯一的 – user647445 2011-04-01 00:05:20

+0

如果脚本停止,那么guid不存在了吗?所以它不是更多的“链接”到数据库ID。 – 2011-04-01 00:05:25

0

不这个功能做你想做的(无需验资):http://www.php.net/manual/en/function.uniqid.php

+0

这不一定是唯一的db – user647445 2011-04-01 00:04:47

+0

是的,这比使用mt_rand更好。谢谢。但是我的主要问题仍然存在吗? – PHP 2011-04-01 00:05:09

+0

uniqid永远不会返回两次相同的结果。你的意思是你的桌子上已经有数据了吗? – MatTheCat 2011-04-01 00:06:41

0

随机字符串生成...字母,数字,有218 340 105 584 896组合为8个字符。

function randr($j = 8){ 
$string = ""; 
    for($i=0;$i < $j;$i++){ 
     srand((double)microtime()*1234567); 
     $x = mt_rand(0,2); 
     switch($x){ 
      case 0:$string.= chr(mt_rand(97,122));break; 
      case 1:$string.= chr(mt_rand(65,90));break; 
      case 2:$string.= chr(mt_rand(48,57));break; 
     } 
    } 
return $string; 
} 

环......

do{ 
    $id = randr(); 
    $sql = mysql_query("SELECT COUNT(0) FROM table WHERE id = '$id'"); 
    $sql = mysql_fetch_array($sql); 
    $count = $sql[0]; 
}while($count != 0); 
+0

这将会遇到规模问题:随着表格获得更多条目,碰撞的几率会变得更高。 – staticsan 2011-04-01 00:15:26

+0

和我可以插入$ id作为一个正常的变量连同我所有的其他$ _POST变量,什么不是在做之后呢?谢谢你的帮助。 – PHP 2011-04-01 00:15:34

+0

是的你可以,脚本执行将不会继续,直到生成唯一的$ id,意味着没有IF等@staticsan,最终,是的,但仍可以稍微调整。 – 2011-04-01 00:18:31

0

我认为你需要从不同的方向接近的问题,特别是为什么递增的数字序列是不希望的。

如果它需要是一个'不透明'的标识符,你可以做一些事情,比如从一个简单的递增数字开始,然后在它周围添加一些东西,使它看起来不像,例如结尾有三个随机数字。你可以走得更远,然后把一些生成的字母放在前面(随机或基于其他算法,例如他们首次注册的那一天,或者他们打的哪个服务器),然后做一个简单的校验算法,使另一个算法信结束。现在有人无法轻易猜到某个ID,并且在碰到数据库之前就有一种拒绝某种ID的方法。您也需要在ID附近存储附加数据。

如果它需要是一个随机且唯一的数字,那么在告诉新用户之前,您需要使用生成的ID检查数据库。在这种情况下,如果数字空间太小,会遇到规模问题,并且在检查未使用分区之前,您会碰到太多碰撞。如果可能的话,那么你将需要将你的ID生成分为两部分:第一部分将用于找到所有具有该前缀的ID,然后你可以生成一个新的,不存在于你的设置中从DB获得。

+0

谢谢你,这是一个完全不同的方法,我会研究。如果我的随机数在10,000到10mill之间,并且数据库上有10,000个用户,同时使用mdrand运行while循环,可能会有多少问题?它可能是那么糟糕吗?我从来没有把它看得这么深。 – PHP 2011-04-01 00:51:24

0

对于初学者,我总是喜欢在php中做所有的随机工作。

function gencode(){ 
$tempid=mt_rand(5000, 1000000); 
$check=mysql_fetch_assoc(mysql_query("SELECT FROM users WHERE id =$tempid",$link)); 
if($check)gencode(); 
$reg=mysql_query("INSERT INTO users id VALUES ('$tempid')",$link); 
//of course u can check for if $reg then insert successfull