2015-05-10 57 views
0

我期待根據MySQL數據庫生成一個沒有重複的隨機數。我如何更改以下函數,以便它檢查數據庫,如果生成的數字已經存在,並且如果不存在,則將其插入到表中。另外,如何佈置表格?我不是最好的設計行,使他們儘可能小(和實用)。生成非重複數字,對數據庫保持警惕

功能:

function genNonRepNum($min, $max, $quantity) { 
    $numbers = range($min, $max); 
    shuffle($numbers); 
    return array_slice($numbers, 0, $quantity); 
} 


使用功能:

print_r(genNonRepNum(1000, 10000, 3)); 

回報:

Array ([0] => 8586 [1] => 9666 [2] => 8169) 

這是真棒,但我只希望它檢查一個數據庫,看看它是否存在,如果沒有,就插入它。提前致謝。

+0

使db索引唯一,那麼現有數字的任何插入都將失敗 –

+0

這可以解決插入它們的問題,但它並不能真正回答我的問題。另外,如果我使用它,我是否必須使用'try'塊來插入它們,如果它失敗了,或者如果我打電話它會好嗎? – Zak

+1

在問題中沒有插入,我不知道你的方法 –

回答

2

此處的解決方案是對自動遞增數字使用加密。作爲我的意思的一個例子,想象一下你有一個加密算法,它採用8位密鑰並且輸出8位加密數據。如果您使用了相同的密鑰並對值0至255進行了加密,則會以不同的順序輸出所有0到255的值。您無法獲取任何重複項,因爲按定義加密是可逆的,這意味着兩個不同的值無法使用相同的密鑰和算法加密爲相同的值,因爲您無法解密它。由於像雪崩效應這樣的密碼質量,數字序列會顯得隨機。所以基本上,你只需要用一個祕密密鑰來加密一個自動遞增的數字,根據你的質量和速度需求使用你選擇的算法。這就是新的信用卡號碼的生成方式,同時表示卡號還沒有發出。有關更多信息,請查閱「格式保留加密」。

+0

順便說一句,這也是一個很好的方式來洗牌大型列表或大範圍的值,而不必實際洗牌或存儲列表。 –

+0

我非常喜歡這個主意。謝謝!我可以從這裏弄出一切。 – Zak

+0

太棒了!祝你好運,並與朋友分享技術。它非常有用,但人們似乎並不知道它:p –

0

我認爲這不是你應該去做的方式只是使用php openssl-random-pseudo-bytes它給你一串隨機字節(任何加密安全的隨機生成器/散列函數,可以創建不可預知的安全ID將完成工作) - 這個將給是肯定不同的(或極不可能在理論上是相同的)鍵,或者如果你想有一個很好的使用次數自動遞增並獲得lastinsert_id通過驅動程序如提供:

mysqli_insert_id() 
PDO::lastInsertId() 

後查詢執行並在軟件中使用它

手動檢查是否插入並重試既貴又不好,應該避免

請儘量保持您的旅行數據庫到最低!!!!!!!

0

首先,通常你不這樣做 - 你可以設計一個足夠大的數字,使得碰撞概率可以忽略不計,然後使用一個強大的隨機生成器來生成這個大小的隨機數。除非你實現某種深奧的密碼方案 - 例如你可以存儲一個計數器並使用AES進行加密;當然這些數字並不是真正的「隨機的」 「,但他們也不容易預測),並且您必須在開始時定義隨機範圍,您可以創建一個已插入隨機數的表格:用連續數字填充表格,然後插入另一個具有唯一通過RAND()進行的auto_increment鍵排序。

現在,當您需要一個隨機數時,您獲取表的第i個元素並讀取其value列,然後遞增i以確保您不重複使用該數字。如果兩個進程都需要一個隨機數,您將需要使用鎖定和事務。

這還有一個好處,就是當號碼池將要變干時,此時您可以插入新號碼。這會稍微隨機(第一百萬個數字在0-999999範圍內是隨機的,第二個百萬個數字將在1000000-1999999範圍內),但是對於您的目的來說也許就足夠了。

或者你可以創建兩個獨特的列

CREATE TABLE randompool (
    id integer not null primary key auto_increment, 
    value integer 
); 
CREATE UNIQUE INDEX randompool_uniq ON randompool(value); 

,並使用二次加工,以檢查隨機表,當一個全局變量的地方保存,NEXT_ID,是說的COUNT(*) FROM randompool 10%之內 - 這意味着隨機池下降到了10%的能力 - 而且,如果是的話,產生一些隨機數和嘗試將它們插入

INSERT IGNORE INTO randompool (value) VALUES (?),(?),(?),... 

當然,更大randompool,效率較低這一Ø peration。當randompool包含2億個數字時,生成一個隨機的帶符號32位數的隨機數將有10%的擊中副本並被拒絕的概率,因此插入1000個新的隨機數將比開始時按比例增加成本;還考慮到索引重複查找會花費更多。沒有更多,但更多。但是,如果這個過程是獨立的,並且在系統負載不太高的情況下運行,這可能不是問題。

隨機數的選擇仍然使用NEXT_ID計數器直接從表中讀取它們,因此讀取數字將非常便宜。