如何生成全局唯一标识
引出
大家都用過(guò)QQ或者微信吧, 當(dāng)我們注冊(cè)的時(shí)候, 會(huì)被自動(dòng)分配一個(gè)QQ號(hào), 這個(gè)號(hào)碼是全局唯一且固定的, 那么, 如果是你來(lái)寫的話, 如何為新注冊(cè)的用戶分配一個(gè)號(hào)碼呢? 亦或是一個(gè)電商網(wǎng)站, 要為每個(gè)訂單生成一個(gè)訂單號(hào)? 再或是一個(gè)即時(shí)聊天, 要為每個(gè)消息生成一個(gè)消息ID?? 我簡(jiǎn)單想了想
方案一
其實(shí)這事說(shuō)簡(jiǎn)單點(diǎn), 不就是要為每個(gè)用戶都配一個(gè)數(shù)字么? 而且這個(gè)數(shù)字必須是之前沒(méi)有用過(guò)的. 那簡(jiǎn)單了, 數(shù)數(shù)就完了唄, 123456往下數(shù), 來(lái)一個(gè)發(fā)一個(gè)記一個(gè).
如何實(shí)現(xiàn)? MySQL主鍵自增, 或者redis記一個(gè)key, 每次incr自增. 什么? QQ號(hào)從1開(kāi)始太丑了? 簡(jiǎn)單, 自增設(shè)置一個(gè)起始ID.
完美, 實(shí)現(xiàn)方案簡(jiǎn)單粗暴, 而且不會(huì)出現(xiàn)重復(fù).
方案二
使用時(shí)間戳. 使用當(dāng)前時(shí)間戳來(lái)生成, 比如: 1585390459 這樣的數(shù)字. 但是時(shí)間戳是以秒為單位的, 如果一秒發(fā)生了多次請(qǐng)求, 那不就重復(fù)了么? 我想了想, 有一個(gè)簡(jiǎn)單到爆的處理方法, 在后面再拼上0000-9999的隨機(jī)數(shù), 這樣每秒有一萬(wàn)個(gè)不重復(fù)的, 重復(fù)的概率就降低了, 在生成后還需要查詢是否已經(jīng)存在, 若存在則重復(fù)生成.
方案三
說(shuō)起來(lái), 要生成這樣的隨機(jī)ID, 總要有一個(gè)地方來(lái)記錄已生成的進(jìn)度, 如果完全隨機(jī)生成的話, 就不可避免的需要回查是否存在. 記錄生成進(jìn)度的可以有很多: redis、MySQL等等. 或者可以存在一個(gè)發(fā)號(hào)器, 所有的ID都有它來(lái)生成, 不停的生成, 供其他請(qǐng)求分配使用, 就是一個(gè)生產(chǎn)者消費(fèi)者.
小結(jié)
通過(guò)想了幾種方案, 發(fā)現(xiàn)了一些規(guī)律.
要想生成隨機(jī)ID, 首先, 要有一個(gè)不是隨機(jī)的而又是當(dāng)前唯一持有的. 在這個(gè)前提下, 再各種添油加醋, 生成最終的ID. 就算你要調(diào)用隨機(jī)函數(shù), 也得設(shè)置一個(gè)隨機(jī)種子不是? 莫非這就是傳說(shuō)中的以不變應(yīng)萬(wàn)變…
很好, 那么現(xiàn)在問(wèn)題就歸結(jié)為, 如何給每個(gè)用戶都配一個(gè)唯一標(biāo)識(shí)
1.數(shù)數(shù)
直接想到的方案, 從1開(kāi)始, 慢慢往后數(shù), 而這個(gè)過(guò)程可以借助MySQL的主鍵自增, 也可以借助redis的單線程優(yōu)勢(shì). 等等吧,
2.用戶特征
可以根據(jù)不同用戶的特征, 如用戶的地域、性別、生辰等等, 來(lái)生成每個(gè)人的唯一標(biāo)識(shí), 此舉可以參考身份證號(hào)碼的生成, 每個(gè)人都是不一樣的
3.當(dāng)前機(jī)器特征
找到執(zhí)行代碼時(shí)的特定特征, 如: mac地址、時(shí)間戳、機(jī)器編號(hào)、線程ID等等
4.代碼運(yùn)行次數(shù)
線程共享變量, 每次執(zhí)行則+1.
等等等等
簡(jiǎn)單想下來(lái), 其實(shí)重要的是找到其中每次生成都和別人不一樣的那個(gè)點(diǎn), 然后拿來(lái)稍作加工即可. 有點(diǎn)找不同的趕腳. 對(duì)了, 在網(wǎng)上看到了twitter的雪花算法, 基本也是找不同的思路. 關(guān)鍵就在于你是否能從各種功能繁雜的信息中找到那個(gè)不同的點(diǎn). 如果實(shí)在找不到不同, 就只能人為的賦予他們不同了(自增ID等).
現(xiàn)在已經(jīng)有很多工具了, uuid, MongoDB的objectid等, 基本可以拿來(lái)直接使用.
總結(jié)
以上是生活随笔為你收集整理的如何生成全局唯一标识的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php取消转译代码,PHP在我不需要的时
- 下一篇: OAuth1.0介绍