每日學習20170224-分庫分表全域性ID生成
阿新 • • 發佈:2018-12-24
由於資料量以及IO效率的因素,很多專案對資料支援的資料庫會採取分庫分表的方式。使用了分庫分表之後需要解決的一個問題就是主鍵的生成。多個表之間的主鍵就不能用資料庫本身的自增主鍵來支援,因為不同表之間生成的主鍵會重複。所以需要其他的方式獲取主鍵ID。
一般來說解決方案主要有三種:
- oracle sequence : 基於第三方oracle的SEQ.NEXTVAL來獲取一個ID 優勢:簡單可用 缺點:需要依賴第三方oracle資料庫
- mysql id區間隔離 : 不同分庫設定不同的起始值和步長,比如2臺mysql,就可以設定一臺只生成奇數,另一臺生成偶數. 或者1臺用0~10億,另一臺用10~20億. 優勢:利用mysql自增id 缺點:運維成本比較高,資料擴容時需要重新設定步長.
- 基於資料庫更新+記憶體分配: 在資料庫中維護一個ID,獲取下一個ID時,會對資料庫進行ID=ID+100 WHERE ID=XX,拿到100個ID後,在記憶體中進行分配 優勢:簡單高效 缺點:無法保證自增順序
考慮到擴充套件性和維護性,我們採取了第三種方案。具體實現為:
- 我們設定獲取ID步長為l,一共有n個表分配id。
- 初始化後,n個表中的id值分別為0,l, 2l,3l…
- 當應用從任意一個表獲取ID,這個表中的ID會在原ID值上增加nl。
舉例說明,步長為100,共4個id表
- 初始化後,4個表中的值分別為, 1:0, 2:100, 3:200, 4:300
- 假設應用從表2獲取了id,那麼四個表的值變為,1:0, 2:500, 3:200, 4:300
這樣一來有如下幾個好處:
- 實現了全域性唯一ID。
- 不影響業務資料庫的擴充套件。
- 獲取ID有容災,單個表無法訪問不影響全域性。