1. 程式人生 > >每日學習20170224-分庫分表全域性ID生成

每日學習20170224-分庫分表全域性ID生成

由於資料量以及IO效率的因素,很多專案對資料支援的資料庫會採取分庫分表的方式。使用了分庫分表之後需要解決的一個問題就是主鍵的生成。多個表之間的主鍵就不能用資料庫本身的自增主鍵來支援,因為不同表之間生成的主鍵會重複。所以需要其他的方式獲取主鍵ID。

一般來說解決方案主要有三種:

  1. oracle sequence : 基於第三方oracle的SEQ.NEXTVAL來獲取一個ID 優勢:簡單可用 缺點:需要依賴第三方oracle資料庫
  2. mysql id區間隔離 : 不同分庫設定不同的起始值和步長,比如2臺mysql,就可以設定一臺只生成奇數,另一臺生成偶數. 或者1臺用0~10億,另一臺用10~20億. 優勢:利用mysql自增id 缺點:運維成本比較高,資料擴容時需要重新設定步長.
  3. 基於資料庫更新+記憶體分配: 在資料庫中維護一個ID,獲取下一個ID時,會對資料庫進行ID=ID+100 WHERE ID=XX,拿到100個ID後,在記憶體中進行分配 優勢:簡單高效 缺點:無法保證自增順序

考慮到擴充套件性和維護性,我們採取了第三種方案。具體實現為:

  1. 我們設定獲取ID步長為l,一共有n個表分配id。
  2. 初始化後,n個表中的id值分別為0,l, 2l,3l…
  3. 當應用從任意一個表獲取ID,這個表中的ID會在原ID值上增加nl。

舉例說明,步長為100,共4個id表

  1. 初始化後,4個表中的值分別為, 1:0, 2:100, 3:200, 4:300
  2. 假設應用從表2獲取了id,那麼四個表的值變為,1:0, 2:500, 3:200, 4:300

這樣一來有如下幾個好處:

  1. 實現了全域性唯一ID。
  2. 不影響業務資料庫的擴充套件。
  3. 獲取ID有容災,單個表無法訪問不影響全域性。