1.公民身份證是如何生產的?
根據中華人民共和國國家標準GB 11643-1999 公民身份號碼規則

示例:

校驗碼公式

校驗碼規則說明

2.分布式系統中"身份證"
分布式系統,有的業務系統,都有生成ID的需求,如訂單id,商品id,文章ID等。這個"身份證"一般要求:
>>全局唯一
>>有序
分布式系統中"身份證"生成常用方法:
1.數據庫生成法
沈劍老師在<細聊分布式ID生成方法>中提到兩個方法:1.單個法(auto_increment) 2.批量法(也稱步長法) 其中詳述了它們的優缺點,我就不一一贅述了。
2.redis生成法
分布式唯一ID極簡教程 中提到,不贅述
3.zk生成法
與redis類似,不贅述。
4.mongo生成法
分布式唯一ID極簡教程 中提到,不贅述
5.類snowflakes生成法
沈劍老師在<細聊分布式ID生成方法>中也提到,不贅述
6.uuid法
沈劍老師在<細聊分布式ID生成方法>中也提到,不贅述
7.msic法
其中,1~6種方法,網上都可以輕易找到,這里就不贅述了。
重點是方式 7,通過業務結合,靈活利用1~6來做,下面是我根據公民身份證唯一的思路來設計訂單號一種方式,僅供參考
說明:
1.時間戳為毫秒級
2.用戶號9位可以滿足大部分系統需求,可以根據系統修正
3.順序碼 3位 是該用戶同時下單的順序碼,先從redis查找,該用戶在1分鐘之內是否有訂單,沒有則設置為1,返回1,否則增加1
4.校驗碼,驗證訂單號是否符合規則,不符合規則的拋棄。

5. 建議使用數據庫+redis緩存方式來做,多庫的時候訂單號也可以加上庫信息

小結:
總體而言,分布式唯一ID需要滿足以下條件:
- 高可用性:不能有單點故障。
- 全局唯一性:不能出現重復的ID號,既然是唯一標識,這是最基本的要求。
- 趨勢遞增:在MySQL InnoDB引擎中使用的是聚集索引,由于多數RDBMS使用B-tree的數據結構來存儲索引數據,在主鍵的選擇上面我們應該盡量使用有序的主鍵保證寫入性能。
- 時間有序:以時間為序,或者ID里包含時間。這樣一是可以少一個索引,二是冷熱數據容易分離。
- 分片支持:可以控制ShardingId。比如某一個用戶的文章要放在同一個分片內,這樣查詢效率高,修改也容易。
- 單調遞增:保證下一個ID一定大于上一個ID,例如事務版本號、IM增量消息、排序等特殊需求。
- 長度適中:不要太長,最好64bit。使用long比較好操作,如果是96bit,那就要各種移位相當的不方便,還有可能有些組件不能支持這么大的ID。
- 信息安全:如果ID是連續的,惡意用戶的扒取工作就非常容易做了,直接按照順序下載指定URL即可;如果是訂單號就更危險了,競爭對手可以直接知道我們一天的單量。所以在一些應用場景下,會需要ID無規則、不規則。
參考資料:
【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