【问题标题】:Generating Unique Values for MySQL Unique Fields为 MySQL 唯一字段生成唯一值
【发布时间】:2015-02-03 09:34:13
【问题描述】:

例如,当用户注册我的网站时,我会创建一个长度为 40 的唯一字符串并将其插入数据库。然后,我们以 URL 的形式向新注册的用户发送包含此唯一字符串的电子邮件,这一切正常。 但是您如何创建和插入此注册实体以确保具有唯一属性的字段实际上是唯一的?

我目前的做法如下:

$key = '';
$repeat = true;
while ($repeat) {
    $key = generate_hash(40);
    $is_unique = (count($model->get_by_key($key)) === 0) ? true : false;
    $repeat = ($is_unique) ? false : true;
}
// At this point I know the key is unique and can insert it...

我对这段代码不满意,因为我通常会尽量避免 while 循环。有没有更好的方法来实现我在这里所做的事情?

底线是包含这些键的 MySQL 字段具有唯一属性,我需要知道插入这些键时不会发生唯一冲突。

【问题讨论】:

  • 看看UUID()
  • 这个字符串必须(全局)唯一吗?还是您希望随机数(非常)难以被猜到?既然你提到了[新用户,注册,电子邮件],我的猜测是:后者。
  • 这些键应该是唯一的。注册用户单击其电子邮件中包含此密钥的链接,该密钥用于确定要解锁哪个用户帐户。这只是使用唯一键的一个例子,必须有更好的方法来生成它们
  • 在您描述的示例中,nonce 不必是全局唯一的 - 只是很难猜到。 please confirm your email account by following the link: http://.....?userid=<thisneedstobeunique>&nonce=<thisonlyhastobehardtoguess>,就像借记卡和自动取款机一样:不仅有一张卡有特定的密码,而且有一张特定的卡(id)很难(足够)猜出相应的密码。
  • 好的,所以这里的键不需要是唯一的。在解锁用户帐户之前,我应该确保在数据库中呈现的随机数和用户 ID 匹配。这种方法肯定更好 - 谢谢!

标签: php mysql unique


【解决方案1】:

好的,基本上你有两种方法。

  1. 让数据库处理这个问题并使用 UUID() 创建一个可以在电子邮件中使用的唯一标识符。

    根据您的 MySQL 版本,您有一些选择:

    A. 使用 MySQL 4.1 及以上版本,您可以直接通过 INSERT INTO 使用该函数:

    INSERT INTO table_name 
        (unique_id, field1, field2) 
    VALUES 
        (UUID(), "smth", "smth")
    

    B. 使用 MySQL 5.0,您可以创建 TRIGGER 并在插入时自动填充唯一字段:

    CREATE TRIGGER 
    unique_id
    BEFORE INSERT ON 
    table_name 
    FOR EACH ROW
    SET NEW.unique_id = UUID()
    
  2. 您可以通过程序检查生成的 id 是否真的是唯一的。你现在正在做同样的事情,但你可以像这样重构代码:

    $key = generate_hash(40);
    while ( count($model->get_by_key($key)) ) {
        $key = generate_hash(40);
    }
    
    //here you have an unique id in $key 
    

【讨论】:

    【解决方案2】:

    几乎每种语言都内置了唯一的 id 函数。在 php 中,

    echo uniqid();
    

    【讨论】:

      【解决方案3】:

      您可以生成 256^40 个不同的 40 个字符的字符串。 在您生成 2 个相同的字符串之前,Sun 会爆炸。

      【讨论】:

        【解决方案4】:

        您可以改用md5(time()) 作为您的唯一值。 md5time 不会对于每个提交的用户都相同。

        $time = time();
        $md5 = md5($time);
        

        只要md5()只包含32个字符串长度,就可以在md5()后面加一个唯一的词。

        $unique = $md5."uniq1234";
        

        现在你有 40 个唯一的字符串长度。最后你可以添加$unique作为你在数据库中的唯一值

        【讨论】:

          【解决方案5】:

          你可以使用这个函数来生成uniqueID,

          function keygen($length=10)
          {
              $key = '';
              list($usec, $sec) = explode(' ', microtime());
              mt_srand((float) $sec + ((float) $usec * 100000));
          
              $inputs = array_merge(range('z','a'),range(0,9),range('A','Z'));
          
              for($i=0; $i<$length; $i++)
              {
                  $key .= $inputs{mt_rand(0,61)};
              }
              return $key;
          }
          
          echo keygen(10);
          

          【讨论】:

            猜你喜欢
            • 2017-04-23
            • 2018-04-21
            • 1970-01-01
            • 2011-05-21
            • 2011-06-20
            • 1970-01-01
            • 2017-01-08
            • 2010-10-05
            • 1970-01-01
            相关资源
            最近更新 更多