非主要领域的独特价值

时间:2011-12-14 19:43:17

标签: php mysql md5 unique

我正在使用php生成一个随机10个字符的字符串,并将其插入到我的数据库中的一列中。我的问题是我希望这个字符串是唯一的(在数据库中)。我已经想到了很多这样做的方法,但想知道哪种方式最有效。

我的PHP看起来像这样(随机字符串只能是10个字符长):

 //generates an almost unique(not quite) ticket number
 $pretrimmedtask = md5(uniqid(mt_rand(),true));
 $tasknum =  substr($pretrimmedtask ,0,10);
然后,我接受这个“唯一”值并插入它。但由于字符串的修剪,这个值绝不是唯一的。我想知道什么是最好的方法来确保这个价值永远不会重复,同时仍然有效。

(据我所知,查询db以查找此值有可能......但我宁愿以更优雅的方式进行此操作)

4 个答案:

答案 0 :(得分:1)

创建仅覆盖该字段的唯一mysql索引,并将该值插入循环中直到成功。

像:

while (true) {
    $random = generate it;
    try to insert;
    if (inserted without errors) break;
}

答案 1 :(得分:1)

您应该更新您的表并使相关列成为UNIQUE KEY,而不是尝试插入生成的字符串,如果没有插入行,则生成另一个键并重试。

ALTER TABLE table_name ADD UNIQUE KEY (column_name);

下面的代码会尝试INSERT table1中的新行,如果无法,则会使用其他随机生成的$key重试。

IE。如果col2具有唯一键约束且列中已存在$key的值,则查询将不会成功。

function generate_random_string () {
  $charset = array_merge (
    range ('a', 'z'), range ('A','Z'), range ('0','0')
  );

  shuffle ($charset);

  return join ('', array_slice ($charset, 0, 9));
}

/* ....................................................... */

do {
  $key = generate_random_string ();
} while (
  !mysql_query ("INSERT INTO table1 (col1,col2) VALUES (123, '$key')")
);

您当然可以使用自己的算法生成随机字符串。

注意:确保查询可能成功,这样您就不会陷入无休止的循环中。

答案 2 :(得分:0)

是否必须是10个字符。使用crypt(),您可以生成13个字符长的哈希值。

这里http://www.php.net/manual/en/function.hash.php您可以检查不同散列方法的长度。他们中的任何一个都不幸地产生了10个字符长的字符串。但是你可以生成8个字符长的字符串并添加两个字符。

我想出的另一个可能的解决方案是使用生成字符串的当前日期。 Unixtimestamp只是数字和长,但我们可以按以下方式将日期转换为10个字符串

创建两个数组,首先使用1到31的键,并为每个键分配一个字符(26个字母加上10个数字就可以完成),第二个数组需要从0到99的键,并且具有两个字符的值长串。

现在获取当前时间的日,月,年(2位),小时,分钟和秒,并将值替换为数组中的值,其中日期和月份取自第一个数组,其余来自数组第二。结合它,你有10个字符长的唯一字符串。

答案 3 :(得分:0)

我自己有这个问题。

我使用(插入)time()和插入/行id(+特殊字母数组)md5-ed一起作为一个字符串并进行散列 - 出于某些cookie的目的,我们可以说。所以,那把钥匙暴露了。

插入(或行)ID不能重复,并且与unix时间戳(10位数)+随机字母和md5-ed合并在一起创建肯定唯一的“第二密钥”有点难以打破通过cookie可用的内容。在这种情况下是不可能打破它。

但这是一个哈希。

如果10个字符是必不可少的 - 因为我找不到理由 - 您可以创建用于创建按键的功能,如(9999999999999999999-主键)+ substr 10也包含字母,但这取决于曝光的级别那把钥匙。

但是,substr不是一个选项,主键角色很简单 - 必不可少。