2009-09-23 483 views
21

我编程使用PHP和MySQL的脚本,我希望得到一个 唯一ID(包括字符串:首都和用数字小 字母),如:gHYtUUi5b。 我发现PHP中有许多函数可以生成这样的数字,但我担心如何确保id是唯一的!如何在MySQL中生成唯一的ID?

UPDATE:uuid很长,我的意思是这样的id:(P5Dc)一个11个字母数字字符。

+0

你正在寻找的MySQL等同于SQL Server的一个的GUID? – Asaph 2009-09-23 17:55:13

+0

你能解释一下你打算如何使用它? – 2009-09-23 18:03:31

+0

不,我只是谈论像:gHYtUUi5b,短的字母数字字符串。 – assaqqaf 2009-09-23 18:06:09

回答

12

编程方法可以是:

  • 在PHP在PHP
  • 环添加一个唯一索引字段
  • 生成一个随机字符串(而(!DO_THE_INSERT))
    • 产生另一个字符串

注:

  • 这可能是肮脏的,但有优势是DBMS无关
  • 即使你选择使用DBMS特有的唯一ID生成器功能(UUID等) 确保最佳做法是领域必须是唯一的,使用索引
  • 的统计根本没有执行该循环时,只输入上插入失败
+1

这是我脑海中唯一的解决方案,即使在我发布我的问题之前。是使用资源的方式。同时也不科学。相反,它是 – assaqqaf 2009-09-23 18:19:43

+1

。如果顺利完成,实现了安全的,因为数据库管理系统为基础的方法,资源不是问题,如果你生成一个随机字符串是非常非常低的(根据课程表尺寸)的INSERT的概率失败,所以你循环实际上是一个单一的操作。 – drAlberT 2009-09-23 18:28:28

+2

除非你的随机数发生器不是完全随机的。书面竞争条件通常是一个糟糕的想法^ TM – 2010-02-15 17:26:17

45

我使用UUID()来创建一个独特的价值。

例如:

insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID"); 
+1

感谢名单但UUID长,imean这样的ID,如:(P5Dc)一个11个字母数字字符。 – assaqqaf 2009-09-23 18:00:28

+0

它很长,因为它必须保证唯一性:)如果你真的需要使它简短,请参阅我的文章 – drAlberT 2009-09-23 18:03:35

+7

@assaqqaf,可以使用UUID_SHORT()来代替。 – Natasha 2013-01-31 07:47:01

3

使用UUID function

我不知道你的程序在PHP中产生独特的值的来源。如果是图书馆功能,他们应该保证你的价值真的很独特。检查文档。你应该一直使用这个功能。例如,如果您使用PHP函数生成唯一值,然后决定使用MySQL函数,则可以生成已存在的值。在这种情况下,将UNIQUE INDEX放在列上也是一个好主意。

1

举世无双我做的是我把Unix时间戳和随机字符串追加到它并使用它。

+0

ü可以使用microtime中,并将其转换为十六进制,以获得在大多数情况下,串效果或者至少,你若不具有高话务量/插入在DB这会工作正常。 – 2009-09-23 18:17:41

+0

“我用它通过url访问资源,如果我使用auto_increment,它会很容易建议”..保持这一点... 如果插入是高的..你可以通过其他方式做到..使用自动递增添加正常的ID在DB ..网站,在这里显示的链接上,有一个已知的密钥加密的ID,然后用使DB查询之前该密钥解密回来。 – 2009-09-23 19:20:54

+0

,我实际上使用...但我寻找最好的解决方案.. – assaqqaf 2009-09-23 22:07:58

0

以下仅供参考数字唯一随机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(10000,999999) .$randomchar; // assume $radomchar contains char;

0

您还可以考虑使用crypt()*生成您的约束上内[近担保]唯一ID。

19

你可能喜欢我们做的方式。我想要一个看似“随机”的可逆唯一代码 - 这是一个相当常见的问题。

  • 我们取一个输入数字,比如1,942。
  • 左垫成一个字符串:“0000001942”
  • 把最后两个数字到前:“4200000019”
  • 转换到这一个号码:4200000019

我们现在有一个数字,不同通话间的差异很大,保证不超过10,000,000,000。开始不错。

  • 转换该号码到一个基座34的字符串: “2oevcyb”
  • 升挡: “2OEVCYB”
“2oevc0b”
  • 与 'Y' 替换任何零和与 'Z' 的任何那些

    选择底座34的原因是我们不必担心0/O和1/l碰撞。现在您可以使用一个简短的随机查找键来查找LONG数据库标识符。

  • +0

    我忘记了 - 如果您在第一次将其转换回数字后再添加1,000,000,000,那么您就避免了YYYYYYYY5问题(mangling bases意味着足够大的非常规基数看起来足够随机)。只是不要忘记在回来的路上把它减掉:) – RJStanford 2011-04-21 13:33:44

    4

    如何生成unique_ids是一个有用的问题 - 但您似乎正在对进行反生产假设,当您生成时!

    我的观点是,您不需要在创建行时生成这些唯一的ID,因为它们本质上与要插入的数据无关。

    我所做的是预先生成唯一的ID以供将来使用,这样我可以把自己的甜蜜时间拿出来,绝对保证它们是唯一的,并且在插入时不需要做任何处理。

    例如我有一个order_id的订单表。当用户输入订单时,此ID将随时生成,并会永久增加1,2,3等。用户不需要看到这个内部ID。

    然后我有另一个表 - unique_ids与(order_id,unique_id)。我有一个每天晚上运行的例程,它预先载入足够的unique_id行,以覆盖可能在未来24小时内插入的订单。 (如果我在某一天得到10000个订单,我会遇到问题 - 但这会是一个很好的问题!)

    此方法保证唯一性,并将任何处理负载从插入事务处理并进入批处理例程,它不影响用户。

    +0

    真的不明智!生成一个随机字符串对于服务器硬件来说太快了,以至于你已经完成了太多的工作 – azerafati 2015-12-30 12:48:31

    +0

    “我所做的是预先生成唯一的ID以备将来使用,这样我就可以把我自己的甜蜜时间和绝对保证它们独一无二” 除非在插入时检查,否则您如何知道数据库中尚不存在该ID? – 2016-10-12 14:24:59

    0
    <?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"; 
        ?> 
    
    0

    crypt()的建议,并在一些配置文件存储盐,从1开始的盐,如果你发现重复移动到下一个值2.可以使用2个字符,但会给你足够的盐组合。

    您可以从openssl_random_pseudo_bytes(8)生成字符串。所以这应该给与随机和短字符串(11个字符)与crypt()运行时。

    从结果中去除盐,只有11个字符应该足够随机的为100+百万,如果你在每次随机失败时改变盐。

    3

    如果你使用MySQL比5.7.4更高版本,可以使用新增的RANDOM_BYTES功能:

    SELECT TO_BASE64(RANDOM_BYTES(16)); 
    

    这将导致一个随机字符串,如GgwEvafNLWQ3+ockEST00A==

    0

    这会产生随机的ID:

    CREATE TABLE Persons (
        ID Integer PRIMARY KEY AUTOINCREMENT, 
        LastName varchar(255) NOT NULL, 
        FirstName varchar(255), 
        Age int 
    ); 
    
    +0

    这是答案吗? – Billa 2018-03-04 05:11:01

    +0

    这不会产生* random * ids,它会产生增量id。 – Rob 2018-03-04 05:32:06