真假唯一數,PHP唯一數,Java唯一數,Node唯一數

在真實的業務場景中生成唯一數是很常用的功能,也是面試必考題。最近面試一個PHP開發崗位,無意中聊到這個話題,然后順著話題一直拓展。今天說下在面試中,面試官問這個問題想得到怎樣的答案。

每種編程語言都提供了唯一數生成函數,但是都有條件限制,先看看網上都有哪些生成唯一數的方法。

一. 散列+時間+隨機值

md5(time() . mt_rand(1,1000000));

time()函數獲取當前時間戳,mt_rand(1,1000000)函數獲取一個1到1000000的隨機值,看著好像生成的數能唯一,但這行代碼的問題其實非常多。

在代碼中時間是很不靠譜的參數,如果用戶1秒內發送了2個請求,那么time()字段毫無意義。

在代碼中隨機數其實并不隨機,常見的隨機數都需要有隨機種子,而為了保證種子不被猜到,編程語言默認會使用當前系統時間作為種子。又變成了依賴時間的一個參數,所以這種方案不可取。

二. 微秒+進程編號

uniqid();

uniqid()函數可以得到一個基于微秒和進程編號的唯一ID。對于php-fpm來說,每個請求都獨占一個進程,一個進程會串行的處理多個請求。所以通過進程編號+微秒時間看上去能生成唯一ID。但深究之后發現并不靠譜。

1秒等于100萬微秒,現在問題會變成一個進程能在百萬分之一秒內處理多個請求嗎?答案是可以的,用當前最普通的CPU來說,單核心1秒就可以計算20億次,1微秒可以計算2千次。從計算機調度的角度來說,2千次同時處理到一個進程的兩個請求是完全可能的。所以又變成了依賴時間的一個參數,這種方案不可取。

你還能使用納秒,皮秒等精度更高的時間參數,但以發展的遠光看問題,未來CPU的算力會越來越快,依賴時間的唯一性會越來越差。無論怎么努力,只依靠編程語言自身得到唯一ID是非常困難的,也是我不推薦的。

三. 數據庫

靠編程語言自己走不通,那就通過第三方工具,這種方案是靠譜的。但實現起來也有很多種方法。

LOCK TABLES id_maker;
//拿到id
select id from id_maker; 
//加1更新
update id_maker set id=id+1;
UNLOCK id_maker;

這是我曾經見過的一種id_maker用法,這樣每次得到的id都是唯一并且有序的。但問題就是需要鎖表,性能不高,在高并發下會發生資源搶占導致數據庫崩潰。

//id_maker表有自增id和內容data兩個字段
insert into id_maker(data) values('');
select last_insert_id();

這種方式性能就高很多,insert語句不會鎖表,自增id百分百保證唯一性且有序。唯一的問題是需要定期刪除歷史數據,對于大部分項目我都建議使用這種方式生成唯一ID。

除了MySQL還有MongoDB,Redis等其他數據庫方案,方法大同小異。但是這個方案有局限性,當我們的業務發展到成千上萬臺服務器時通過一個數據庫的一張表去生成ID會導致性能下降拖垮其他服務,還會形成單點依賴。

四. 微秒+服務器編號+計數器

這是twitter使用的一種方案,名字叫SnowFlake,這種方案的原理非常簡單,所以很容易基于SnowFlake算法做擴展。比如PHP并不會常駐內存,計數器的實現就比較麻煩,但只要原理清楚了使用擴展或者數據庫很容易實現。

這個方案的最大優點就是在龐大的集群中,每個服務靠自己就能算出全局的唯一ID。服務器編號和微秒能確定到具體服務器,計數器可以理解為只為當前服務器提供的id_maker,這樣生成的唯一編號無懈可擊。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,057評論 6 13
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發此異常。 O...
    我想起個好名字閱讀 5,386評論 0 9
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,121評論 1 32
  • 分用(Demultiplexing) 目的主機接收到一個以太網數據幀之后,數據幀就開始從網絡協議棧由底層往上升,同...
    牧呈閱讀 365評論 0 0
  • 我仍然想念著的尚好, 近來安好? 我對自己說過的,要放下,要成長,要灑脫,但是一年還是太短,忘不掉。昨晚在備課學習...
    little銫閱讀 168評論 0 0