2009-09-23 25 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