如題,首先謝謝所有來回答的大牛.
描述一下問題:
學習PHP過程中想通過實踐編寫一套推廣系統。推廣地址:**http://xxxx.com/N4aF35aS7**"N4aF35aS7"作為一個識別碼。
現在的問題是:
PHP有函數以微秒層級擷取字元,但是如果考慮到高並發(具體有多高不討論,但需要考慮進來)可能會有重複?另外,識別碼在產生上有規範:1.長度固定(8位左右,太長地址不友好)2.組合形式為大寫、小寫字母,數字(參考百度網盤分享地址)3.絕對不重複,這點很重要4.沒什麼要求了,再謝謝來回答的人。
回複內容:
如題,首先謝謝所有來回答的大牛.
描述一下問題:
學習PHP過程中想通過實踐編寫一套推廣系統。推廣地址:**http://xxxx.com/N4aF35aS7**"N4aF35aS7"作為一個識別碼。
現在的問題是:
PHP有函數以微秒層級擷取字元,但是如果考慮到高並發(具體有多高不討論,但需要考慮進來)可能會有重複?另外,識別碼在產生上有規範:1.長度固定(8位左右,太長地址不友好)2.組合形式為大寫、小寫字母,數字(參考百度網盤分享地址)3.絕對不重複,這點很重要4.沒什麼要求了,再謝謝來回答的人。
我提一種方法:預先處理標識符
提前通過演算法產生絕對不重複的標識符,這個過程中可以自己進行測試,而且因為是預先處理的,不需要考慮時間和演算法複雜性。
將產生的不重複的標識符寫入資料庫
在高並發的情境下只使用讀取操作
上面主要是解決了高並發下的快速響應問題,那麼唯一性如何保證呢?
有兩個思路:
使用隊列進行讀取,保證所有的讀取都是通過唯一的隊列來完成,比如使用redis的pop操作
使用sql的update命令,這個時候需要另外一個欄位userid, 虛擬碼:update TABLE set userid = $userid where userid = 0 limit 1;
,然後再使用userid進行查詢對應的標識符即可。
最後,我堅持的觀點是:最開始的時候就把代碼設計的盡量安全,注意,安全方面的問題一定要高優先順序考慮。
至於說,真正的情境中有哪些“高並發”的情境呢?我只想說,出了問題還是要程式員背鍋。
如果要求絕對不重複那我感覺思路有兩個
1.每次隨機產生建立的id資料持久化,然後每次隨機產生的資料查曆史資料是否重複(但是這每次要資料持久化肯定比較消耗效能)
2.按規律累加(比如按日期時間戳記balabala),這樣產生過的就不會重複,但是高並發怎麼不重複應該就要考慮一下了。
想問問題主比較擔心的是並髮狀態下產生相同的識別碼還是比較擔心會產生曆史重複的識別碼?
如果擔心是並髮狀態的話應該考慮你說的微秒層級字元加一定量的隨機數就好了(每位隨機數可以在48-122之間按ASCII轉換為字元),加多幾位就好了,雖說理論上沒有絕對不重複但是機率應該還是很小了
如果考慮曆史重複那我想到的就是一開始說的那兩條了
用鎖機制試試看。。
1 寫檔案每次+1
2 你既然是推廣系統這個唯一碼只要你帶上使用者id那麼就唯一
3 看到這種什麼高並發的問題就覺得是自己閑的蛋疼,整個互連網要處理高並發的公司真不多,拿來那麼多高並發。感覺現在就是,架構,系統,高並發,緩衝成為了程式員的口頭禪了。
可以產生一條 插資料庫 建個唯一索引 讓資料庫給你去重
根據資料庫中唯一ID產生一個對應的62進位字串。
比較多的文章分析短網址的規則都是產生62進位,理論上ID不重複也不會重複產生字串,但是長度是會變的。看是否可接受。
沒有那麼多真正高並發的事,要求高用使用者ID也是一種辦法。