您好,登錄后才能下訂單哦!
什么是數據庫主鍵 ID 生成策略?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
前言:
系統唯一 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 字符串了。 每次的都不一樣。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。