hilo高低位算法的優勢和用途(非Hibernate主鍵策略)

開門見山地說,hilo高低位算法的用途,或者說目前爲止我所見過的用途,就是——編號生成!
java

一般訂單編號、產品編號、物流編號、工人編號、批次編號等等各類各樣的編號,都是由數字構成,有得會加一些前綴後綴,例如淘寶訂單號。這種編號比較符合咱們的理解和寫記習慣。下面說一下幾點不合理的編號設計。算法

  1. 使用數字型的自增加、序列。這用來表示惟一性沒問題,可是當咱們遇到像訂單編號這種,須要必定長度不太合適。數據庫

  2. 編號須要必定長度,可能你會想到uuid。uuid生成的包含字符,無序、無心義並且也比較長,不符合咱們的寫記習慣,因此uuid作編號也是不合理的。併發

  3. 使用時間戳來當編號,在併發的狀況下精確到毫秒也有可能發生惟一性問題oracle

  4. 使用隨機數加先後綴當編號,不少語言的隨機數都是僞隨機,例如用java每次都new Random(),併發的狀況下有可能取出同樣的數字,就算不併發,誰能保證不會隨機到以前生成過的數字?dom

合理的作法是用表來管理數字主鍵,每次取出來拼接前綴或後綴來當編號,而後+1,就像oracle的序列同樣,由於有些數據庫沒有序列,因此一般爲了統一使用表來管理。性能

hilo高低位算法在這個時候登場了!優化

它解決了一個效率問題——每次取id號都要從數據庫查一遍。ui

詳細分析高低位算法:spa

/*首先有這幾個靜態變量和常量*/
long static final maxLo;//最大低位
long static hi=0;//高位初始化
long static lo=maxLo+1;//低位初始化,這樣是爲了從新初始化的時候進入下面的判斷方法

/*每次生成都進行下面的判斷*/
if(lo>maxLo){//當低位超過最大高位
    long lastValue//表示hi位的進位次數,從數據庫id管理表獲取
    lo=0;//低位歸0
    hi=lastValue*(maxLo+1);//高位進位
    lastValue++//自增並更新到數據庫中
}
long id=ho+lo;
lo++;//低位最後自增

若maxLo設置爲99,按照hi的每次進位劃分,產生的id形式是:

0~99,100~199,200~299,300~399……依此類推,每一個階段99+1個

分析了hilo算法,它其實優化了相似oracle序列這種由數據庫管理的id,每次插入都必須查詢一遍數據庫這種模式,用一個靜態變量低位當成一個oracle序列,當它增加超過設置的最大低位時再查詢數據庫,減小查詢數據庫的次數maxLo倍!從而提高了項目的效率和性能。

Hibernate中的hilo主鍵生成策略的就是爲了提升oracle使用序列當主鍵的效率問題。

若是你不在意這點效率問題,就不用hilo算法了,不過我最後說一下題外話,不管本身寫代碼生成編號使不使用hilo算法,都應該防止併發操做,例如使用java的synchronized。

相關文章
相關標籤/搜索