2009-09-20 32 views
-1

我正在爲UN/LOCODE系統製作代碼生成腳本,並且數據庫在每個國家都有唯一的3個字母/數字代碼。例如,數據庫包含「EE TLL」,EE是國家(愛沙尼亞),TLL是愛沙尼亞境內的唯一代碼,「AR TLL」也可以存在(國家代碼和3字母/數字代碼分開存儲)。代碼是大寫字母。生成獨特的3位字母/數字代碼並與PHP/MySQL中的現有代碼進行比較

該數據庫相當大,已經包含了大量的位置,用戶還可以輸入3個字母/數字(在數據庫自動提交之前檢查)。

最後既不可以使用0或1(可能與O和I混淆)。

我正在尋找的是在未提供任何代碼時選擇下一個可用代碼的最有效方式。

什麼我趕上了:

  1. 我會檢查與AAA至999,但隨後在各碼,將需要一個新的查詢(慢?)。

  2. 我可以將所有40000個可能性存儲在一個數組中,並減去已經存在於數據庫中的所有已使用的代碼......但是使用了太多的內存IMO(不確定我在這裏實際上在說什麼,也許40000不是這麼大的數字)。

  3. 生成一個隨機代碼,並希望它不存在,看看它是否確實,如果它重新開始。這只是冒險。

是否有一些神奇的MySQL查詢/ PHP腳本,可以讓我下一個可用的代碼?

+1

代碼是按順序分配(AAA,AAB等)還是用戶可以輸入任意未使用的代碼? – PatrikAkerstrand 2009-09-20 17:41:08

回答

0

我去了第二個選項。我還能夠製作一個腳本,儘量匹配國家名稱,例如對於塔爾圖,它會嘗試匹配T **然後TA *,如果可能的話TAR,如果不可以,則會嘗試TAT,因爲T是R在塔爾圖之後的下一封信。

的代碼是相當廣泛的,我只是張貼採取第一種可能的代碼部分:

$allowed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789'; 
$length = strlen($allowed); 
$codes = array(); 
// store all possibilities in a huge array 
for($i=0;$i<$length;$i++) 
    for($j=0;$j<$length;$j++) 
     for($k=0;$k<$length;$k++) 
      $codes[] = substr($allowed, $i, 1).substr($allowed, $j, 1).substr($allowed, $k, 1); 

$used = array(); 
$query = mysql_query("SELECT code FROM location WHERE country = '$country'"); 
while ($result = mysql_fetch_array($query)) 
    $used[] = $result['code']; 

$remaining = array_diff($codes, $used); 

$code = $remaining[0]; 

感謝您的意見,這將是運輸代碼世界各地的關鍵:)

0

我會用2號去,很簡單,40000不是一個大數字。

爲了使效率更高,您可以存儲代表每個3個字母代碼的數字。轉換應該是微不足道的,因爲你總共有34(A-Z,2-9)字母。

+0

我不知道我是如何/將34個字母/數字轉換爲數字。但我想第二個選項是一次性操作,如果你說40000很小,那麼確定:) – Solenoid 2009-09-20 18:11:26

+0

Löwis在他的解決方案的第二部分給出瞭解釋。 – phsiao 2009-09-21 13:42:43

0

我會選擇1(即做一個順序搜索),添加一個表,給出每個國家最後分配的代碼(即,使得AAA..code全部被分配)。當通過順序掃描分配新代碼時,該表得到更新;對於用戶分配的代碼,它保持不變。

如果您不想發出重複查詢,也可以將此掃描作爲stored routine寫入。

爲了簡化迭代,最好將三個字母的代碼作爲數字處理(如肖恩蕭的建議),即賦予AZ = 0..25和2..9 = 26..33的含義。然後,XYZ是數字X*34^2+Y*34+Z == 23*1156+24*34+25 == 27429.這應該是可以使用標準的MySQL函數,尤其是使用CONV。

相關問題