惟一性id生成規則研究

無論咱們用什麼方法生成的id,都應該知足如下幾個條件:git

第一 ,  必須是惟一,能夠全局惟一,或者同一種業務內惟一也能夠。github

第二, 必須按時間遞增(這個須要解釋嗎)。redis

第三,儘可能使用數字類型的,其次才考慮字符串型的。緣由很簡單,數字不須要使用編碼(utf-8,gbk等)翻譯。直接能夠保存到數據庫,而字符串必須使用編碼翻譯後才能使用。算法

第四, 在id裏面儘可能能看出id是何時生成的。數據庫

 

關於惟一性id生成討論幾種方案:分佈式

第一種,首選方案,數據庫id自動生成,理由是沒有任何難度,你們都會用。可是這隻能在前期使用,性能

       (1) 當系統負載大了,數據庫性能降低就會考慮更換別的方法了。測試

       (2) 若是有分庫分表的話,也是不能用了,須要想別的辦法替代。ui

第二種, uuid。編碼

這個方案只能說能夠用,能保證惟一 ,用起來簡單,可是用了以後處理有點麻煩,由於不能按時間遞增生成,保存到數據庫的時候對數據庫的性能有影響,至少主鍵索引若是是btree的話,確定會有影響,不過能夠把數據庫主鍵索引改爲hash,具體沒有測試過,按理來講應該是會影響比較小了。有誰測試過了能夠留言說下效果。

第三種,redis。

Redis是單線程的,因此也能夠用來生成全局惟一的ID,利用redis對數字的原子自增操做(Redis的 INCR和INCRBY)。

第四種, twitter的snowflake。

snowflake是Twitter開源的分佈式ID生成算法,結果是一個long型的ID。其核心思想是:使用41bit做爲毫秒數,10bit做爲機器的ID(5個bit是數據中心,5個bit的機器ID),12bit做爲毫秒內的流水號(意味着每一個節點在每毫秒能夠產生 4096 個 ID),最後還有一個符號位,永遠是0。具體實現的代碼能夠參看https://github.com/twitter/snowflake

這種方法能夠保證生成惟一,遞增,數字型的id, 惟一的問題就是生成的id直接看不出是何時生成的。

 

第五種, snowflake 變種。

 (1)  由於long型的十進制只有19位長度,若是咱們要數字型的,又要遞增,又要能從id裏面看出時間,就只有下面這種方法了。

年2位     月2位     日2位     時分4位   數據中心id2位 機器id2位    取納秒的最後5位  
18 01 01 1113 12 15 12345  

這種方法有必定問題,會有重複的id,由於long型長度的限制,咱們時間只能精確到分鐘,一分鐘有60秒,就是60000毫秒, 而後咱們的最後5位最多隻有10萬個數。若是同一臺機器有在同一毫秒內生成多個的話,就可能會出現重複的了。 不過這應該能知足多數需求了。請求量很少的話,這徹底夠用了。

( 2 )    不少時候,19位長度不夠使用,要超過19長度,咱們就只有用字符串來實現了。字符串就比較方便了,能夠任意生成知足咱們須要的id或者訂單號了。

年月日 時分秒 毫秒最後3位 納秒最後6位 數據中心id2位 機器id2位 擴展id 擴展id
180101 121315 876 532524 10 22    

這種方法除了不是數字型的id,幾乎沒有別的缺點了,甚至還能夠再加幾位表示具體的服務的id到裏面。能夠自由擴展,甚至想加具體的業務id均可以。

1801011213158765325241022  最後大概是像這樣的。每毫秒鐘能夠生成十萬個不一樣的id

相關文章
相關標籤/搜索