& lt; PHP>如何在没有自动递增的情况下生成唯一字段


<PHP> how to generate a unique field without auto-increment

我想用这个代码生成一个唯一的id:

$ RCode = md5(函数(rand(),真的));

然后我希望它检查我的数据库,如果RCode是唯一的。

如果不是,我希望它再次使用这部分代码并再次检查我的数据库,如果它是唯一的,

如果它是唯一的,它应该写入我的数据库。

我有检查和写入数据库所需的所有代码,我只是不知道如何使它循环回到开始

感谢帮助!

提前感谢!

一开始就不要检查了。相反,在列上放置唯一约束,这样如果RCode不是唯一的,插入将失败。然后,您可以处理该错误/异常并尝试另一个散列。碰撞的概率很低,所以在这种情况下,你可能不会撞击数据库。

do-while循环的典型例子。

一些PHP-pseudocode:

do {
    $rcode = md5(uniqid(rand(), true));
    $res = mysql_result(mysql_query("SELECT COUNT(*) FROM records WHERE rcode='$rcode'"));
} while ($res[0] > 0);
mysql_query("INSERT INTO records (rcode) VALUES ('$rcode')");
$found = false;
while (! $found) {
  //try..
  if (...unique...) {
    $found = true;
  }
}

从头开始就像实现while循环一样简单。见鬼,你甚至可以使用goto(开玩笑!)

但是我不明白为什么你不想使用auto_increment

你可以使用"loop forever then break out on success"方法:

while (true) {
    $RCode = ...;
    if ($RCode does not exist in db) {
        break;
    }
}
write to the db

编辑:或者更好,确保字段有唯一约束,然后通过检查插入失败来测试唯一性:

while (true) {
    $RCode = ...
    try to insert RCode
    if (no failure) {
        break;
    }
}

这个答案与您的问题略有不同,但它以一种不同的方式解决了唯一ID的问题,根据您的应用程序使用这种方式可能会更好。

老实说,我喜欢使用变量,如日期和时间与另一个变量,如IP地址相结合的这种类型的事情,你可以非常肯定,你的ID将是唯一的,因为日期和时间不会重复出现,在同一秒钟有2个请求的情况下,用户的IP地址在这个时候也是完全唯一的。而且不用查数据库。例如

$idstring = date('Ymdhis');
$ipstring = $_SERVER['REMOTE_HOST'];
$hashme = $idstring.$ipstring;
$idhash = md5($hashme);
我希望这是有帮助的。

当您使用md5()uniqid()返回值进行散列时(任何其他散列算法也是如此),获得不是唯一字符串的可能性极低。

在我看来,它太低了,检查字符串是否唯一是多余的。

你所需要做的就是在数据库中插入值。它将是独一无二的!

编辑:

您应该使用uniqid(null, true)来获得23个字符长的唯一字符串。如果这是你需要的-唯一字符串。

你可以在时间戳上运行MD5…

$uniqueid = md5(time());

首先,不要md5 uniqueiduniqueid已经足够好了,如果单独使用,它没有md5的开销。

第二,隐藏一个自动递增的数字比使用UUID或其他等价的东西要好得多。

但是,如果你必须:

do {
    $rcode = uniqid(rand(), true);
    $res = mysql_query("SELECT COUNT(*) FROM records WHERE rcode='$rcode'");
} while ($res && mysql_num_rows($res));
mysql_query("INSERT INTO records (rcode) VALUES ('$rcode')");
// OR!
// assuming unique index on rcode
do {
    $rcode = uniqid(rand(), true);
} while (mysql_query("INSERT INTO records (rcode) VALUES ('$rcode')"););