首頁  >  文章  >  資料庫  >  資料庫主鍵 ID 產生策略

資料庫主鍵 ID 產生策略

藏色散人
藏色散人轉載
2019-08-15 14:21:303541瀏覽

前言: 

系統唯一 ID 是我們在設計一個系統的時候常常會遇見的問題,以下介紹一些常見的 ID 產生策略。

● Sequence ID

● UUID

● GUID

● COMB

● Snowflake

最開始的自增ID 為了實現分庫分別的需求,會在自增的前提下,使用不同起點,但需要做資料庫拓展時,極為麻煩。例如剛開始時,我們設計某個系統的資料庫時,這個資料庫中會有10 個表,那麼我們對於每個表的內容都需要不同的ID 我們就可以使用不同不長自增的形式,例如,第一張表的是1、11、21、31。 。 。第二張表是 2、12、22、32。 。 。第三張表是 3、13、23、33。 。 。第十張表就是 10、20、30。 。 。但這樣的問題就是,如果有一天我發現這個系統的 10 張表已經不夠用了,我想要再增加一張表,那麼這時的主鍵該怎麼分配呢?另外,如果對於多個資料庫的資料希望合併,但是對於這種簡單的生成 ID 方式,重複的可能性很大,所以幾乎一定會發生重複這種情況。  顯然,如果使用先前的方法的可擴展性會比較差。

比較自增ID,UUID 產生唯一主鍵更方便(資料量非常大的情況下,存在重複的可能),但由於UUID 的無序性,效能不如自增ID,字串儲存,儲存空間大,查詢效率低。關鍵:使用 uuid 的缺點是查詢效率低啊!  

COMB 相對於 UUID,增加了產生 ID 的順序性,插入與查詢效率都有提升。這篇文章有簡單的分析。

Sonwflake 是 Twitter 主鍵產生策略,可以看做是 COMB 的改進,用 64 位元的長整型取代 128 位元的字串。 ID 構成:第一位 0 41 位元的時間前綴 10 位元的節點標識 12 位元的 sequence 避免併發的數字。

第一部分:Sequence ID


資料庫自增長序列或字段,最常見的方式。由資料庫維護,資料庫唯一。

優點:

簡單,程式碼方便,效能可以接受。

數字 ID 天然排序,對分頁或需要排序的結果很有幫助。

缺點:

不同資料庫語法和實作不同,資料庫遷移的時候或多資料庫版本支援的時候需要處理。

在單一資料庫或讀寫分離或一主多從的情況下,只有一個主庫可以產生。有單點故障的風險。

在效能達不到要求的情況下,比較難於擴充。

如果遇見多個系統需要合併或涉及到資料遷移會相當痛苦。

分錶分庫的時候會有麻煩。

優化方案:

針對主函式庫單點,如果有多個Master 函式庫,則每個Master 函式庫設定的起始數字不一樣,步長一樣,可以是Master 的個數。

例如:Master1 產生的是 1,4,7,10,Master2 產生的是 2,5,8,11 Master3 產生的是 3,6,9,12。這樣就可以有效產生叢集中的唯一 ID,也可以大幅降低 ID 產生資料庫操作的負載。

第二部分:UUID


npm 管理   https://www.npmjs.com/package/uuid 

#常見的方式,128 位。可以利用資料庫也可以利用程式生成,一般來說全球唯一。

UUID 是 128 位元的全域唯一標識符,通常由 32 個位元組的字串表示。它可以保證時間和空間的唯一性,也稱為 GUID,全稱為:UUID ―― Universally Unique IDentifier,Python 中叫做 UUID。

它透過 MAC 位址、時間戳記、命名空間、隨機數、偽隨機數來保證產生 ID 的唯一性。

UUID 主要有五個演算法,也就是五種方法來實作。

(1)、uuid1()

――基於時間戳記。由 MAC 位址、當前時間戳記、隨機數產生。可以確保全球範圍內的唯一性,但 MAC 的使用同時帶來安全性問題,在區域網路中可以使用 IP 來取代 MAC。

(2)、uuid2()

基於分散式計算環境 DCE(Python 中沒有這個函數)。演算法與 uuid1 相同,不同的是把時間戳記的前 4 個位置換成 POSIX 的 UID。實際中很少用到該方法。

(3)、uuid3()

基於名字的 MD5 雜湊值。透過計算名字和命名空間的 MD5 雜湊值得到,保證了同一命名空間中不同名字的唯一性,和不同命名空間的唯一性,但同一命名空間的同一名字產生相同的 uuid。

(4)、uuid4()

基於隨機數。由偽隨機數得到,有一定的重複機率,該機率可以計算出來。

(5)、uuid5()

基於名字的 SHA-1 雜湊值。演算法與 uuid3 相同,不同的是使用 Secure Hash Algorithm 1 演算法。

優點:

簡單,程式碼方便。

全球唯一,在遇見資料遷移,系統資料合併,或資料庫變更等情況下,可以從容應對。

缺點:

沒有排序,無法保證趨勢遞增。

UUID 往往是使用字串存儲,查詢的效率比較低。

儲存空間比較大,如果是海量資料庫,就需要考慮儲存量的問題。

傳輸資料量大

無法讀取。

優化方案:

為了解決 UUID 不可讀,可以使用 UUID to Int64 的方法。

第三部分: GUID


GUID:是微軟對 UUID 這個標準的實作。 UUID 還有其它各種實現,不只 GUID 一種。優缺點同 UUID。

第四部分: COMB


COMB(combine)型是資料庫特有的設計思想,可以理解為一種改進的GUID,它透過組合GUID 和系統時間,以使其在索引和檢索事有更優的效能。

資料庫中沒有 COMB 類型,它是 Jimmy Nilsson 在他的 “The Cost of GUIDs as Primary Keys” 一文中設計出來的。 \

COMB 資料類型的基本設計想法是這樣的:既然UniqueIdentifier 資料因毫無規律可言造成索引效率低下,影響了系統的效能,那麼我們能不能透過組合的方式,保留UniqueIdentifier 的前10 個位元組,用後6 個位元組表示GUID 產生的時間(DateTime),這樣我們將時間資訊與UniqueIdentifier 組合起來,在保留UniqueIdentifier 的唯一性的同時增加了有序性,以此來提高索引效率。

優點:

解決 UUID 無序的問題,在其主鍵產生方式中提供了 Comb 演算法 (combined guid/timestamp)。保留 GUID 的 10 個位元組,用另 6 個位元組表示 GUID 產生的時間 (DateTime)。

效能優於 UUID。

第五個部分: Twitter 的 snowflake 演算法


snowflake 是 Twitter 開源的分散式 ID 產生演算法,結果是一個 long 類型的 ID。其核心思想是:使用41bit 作為毫秒數,10bit 作為機器的ID(5 個bit 是資料中心,5 個bit 的機器ID),12bit 作為毫秒內的流水號(意味著每個節點在每毫秒可以產生4096 個ID),最後還有一個符號位,永遠是0。 snowflake 演算法可以根據自身專案的需要進行一定的修改。例如估算未來的資料中心個數,每個資料中心的機器數以及統一毫秒可以能的並發數來調整在演算法中所需的 bit 數。

優點:

不依賴資料庫,靈活方便,且效能優於資料庫。

ID 依照時間在單機上是遞增的。

缺點:

在單機上是遞增的,但是由於涉及到分散式環境,每台機器上的時鐘不可能完全同步,也許有時也會出現不是全域遞增的情況。

六、使用

這個使用起來是真的很方便:

npm install uuid --save

然後就可以使用啦!

  const uuidv1 = require(‘uuid/v1‘);
  console.log(‘随机uuid字符串‘, uuidv1());

這樣,我們就可以印出來 uuid 字串了。每次的都不一樣。

以上是資料庫主鍵 ID 產生策略的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除