1.公民身份證是如何生產(chǎn)的?
根據(jù)中華人民共和國國家標(biāo)準(zhǔn)GB 11643-1999 公民身份號碼規(guī)則
示例:
校驗(yàn)碼公式
校驗(yàn)碼規(guī)則說明
2.分布式系統(tǒng)中"身份證"
分布式系統(tǒng),有的業(yè)務(wù)系統(tǒng),都有生成ID的需求,如訂單id,商品id,文章ID等。這個"身份證"一般要求:
>>全局唯一
>>有序
分布式系統(tǒng)中"身份證"生成常用方法:
1.數(shù)據(jù)庫生成法
沈劍老師在<細(xì)聊分布式ID生成方法>中提到兩個方法:1.單個法(auto_increment) 2.批量法(也稱步長法) 其中詳述了它們的優(yōu)缺點(diǎn),我就不一一贅述了。
2.redis生成法
分布式唯一ID極簡教程 中提到,不贅述
3.zk生成法
與redis類似,不贅述。
4.mongo生成法
分布式唯一ID極簡教程 中提到,不贅述
5.類snowflakes生成法
沈劍老師在<細(xì)聊分布式ID生成方法>中也提到,不贅述
6.uuid法
沈劍老師在<細(xì)聊分布式ID生成方法>中也提到,不贅述
7.msic法
其中,1~6種方法,網(wǎng)上都可以輕易找到,這里就不贅述了。
重點(diǎn)是方式 7,通過業(yè)務(wù)結(jié)合,靈活利用1~6來做,下面是我根據(jù)公民身份證唯一的思路來設(shè)計(jì)訂單號一種方式,僅供參考
說明:
1.時間戳為毫秒級
2.用戶號9位可以滿足大部分系統(tǒng)需求,可以根據(jù)系統(tǒng)修正
3.順序碼 3位 是該用戶同時下單的順序碼,先從redis查找,該用戶在1分鐘之內(nèi)是否有訂單,沒有則設(shè)置為1,返回1,否則增加1
4.校驗(yàn)碼,驗(yàn)證訂單號是否符合規(guī)則,不符合規(guī)則的拋棄。
5. 建議使用數(shù)據(jù)庫+redis緩存方式來做,多庫的時候訂單號也可以加上庫信息
小結(jié):
總體而言,分布式唯一ID需要滿足以下條件:
- 高可用性:不能有單點(diǎn)故障。
- 全局唯一性:不能出現(xiàn)重復(fù)的ID號,既然是唯一標(biāo)識,這是最基本的要求。
- 趨勢遞增:在MySQL InnoDB引擎中使用的是聚集索引,由于多數(shù)RDBMS使用B-tree的數(shù)據(jù)結(jié)構(gòu)來存儲索引數(shù)據(jù),在主鍵的選擇上面我們應(yīng)該盡量使用有序的主鍵保證寫入性能。
- 時間有序:以時間為序,或者ID里包含時間。這樣一是可以少一個索引,二是冷熱數(shù)據(jù)容易分離。
- 分片支持:可以控制ShardingId。比如某一個用戶的文章要放在同一個分片內(nèi),這樣查詢效率高,修改也容易。
- 單調(diào)遞增:保證下一個ID一定大于上一個ID,例如事務(wù)版本號、IM增量消息、排序等特殊需求。
- 長度適中:不要太長,最好64bit。使用long比較好操作,如果是96bit,那就要各種移位相當(dāng)?shù)牟环奖悖€有可能有些組件不能支持這么大的ID。
- 信息安全:如果ID是連續(xù)的,惡意用戶的扒取工作就非常容易做了,直接按照順序下載指定URL即可;如果是訂單號就更危險了,競爭對手可以直接知道我們一天的單量。所以在一些應(yīng)用場景下,會需要ID無規(guī)則、不規(guī)則。
參考資料:
【1】https://mp.weixin.qq.com/s/0H-GEXlFnM1z-THI8ZGV2Q
【2】https://mp.weixin.qq.com/s?__biz=MzI4NDY5Mjc1Mg==&mid=2247484269&idx=1&sn=795446b290f75c3129c50f8fa2e0b2c8&chksm=ebf6db12dc815204e81f6fddc4e690c3315c0e3ce71753b73720e74d47b9d08c633a617ccd95&scene=27#wechat_redirect