溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

什么是數(shù)據(jù)庫(kù)主鍵 ID 生成策略

發(fā)布時(shí)間:2020-07-21 13:44:41 來(lái)源:億速云 閱讀:251 作者:Leah 欄目:MySQL數(shù)據(jù)庫(kù)

什么是數(shù)據(jù)庫(kù)主鍵 ID 生成策略?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

                                                           前言: 

系統(tǒng)唯一 ID 是我們?cè)谠O(shè)計(jì)一個(gè)系統(tǒng)的時(shí)候常常會(huì)遇見(jiàn)的問(wèn)題,下面介紹一些常見(jiàn)的 ID 生成策略。

● Sequence ID

● UUID

● GUID

● COMB

● Snowflake

最開(kāi)始的自增 ID 為了實(shí)現(xiàn)分庫(kù)分別的需求,會(huì)在自增的前提下,使用不同起點(diǎn),但需要做數(shù)據(jù)庫(kù)拓展時(shí),極其麻煩。 比如剛開(kāi)始時(shí),我們?cè)O(shè)計(jì)某個(gè)系統(tǒng)的數(shù)據(jù)庫(kù)時(shí),這個(gè)數(shù)據(jù)庫(kù)中會(huì)有 10 個(gè)表,那么我們對(duì)于每個(gè)表的內(nèi)容都需要不同的 ID 我們就可以使用不同不長(zhǎng)自增的形式,比如,第一張表的是 1、11、21、31。。。 第二張表是 2、12、22、32。。。 第三張表是 3、13、23、33。。。 第十張表就是 10、20、30。。。 但是這樣的問(wèn)題就是,如果有一天我發(fā)現(xiàn)這個(gè)系統(tǒng)的 10 張表已經(jīng)不夠用了,我想要再添加一張表,那么這時(shí)的主鍵應(yīng)該怎么分配呢? 另外,如果對(duì)于多個(gè)數(shù)據(jù)庫(kù)的數(shù)據(jù)希望合并,但是對(duì)于這種簡(jiǎn)單的生成 ID 方式,重復(fù)的可能性很大,所以幾乎一定會(huì)發(fā)生重復(fù)這種情況。  顯然,如果使用之前的方法的可擴(kuò)展性會(huì)比較差。

相比自增 ID,UUID 生成唯一主鍵更加方便(數(shù)據(jù)量非常大的情況下,存在重復(fù)的可能),但由于 UUID 的無(wú)序性,性能不如自增 ID,字符串儲(chǔ)存,儲(chǔ)存空間大,查詢效率低。關(guān)鍵:使用 uuid 的缺點(diǎn)是查詢效率低??!

COMB 相對(duì)于 UUID,增加了生成 ID 的有序性,插入與查詢效率都有所提高。 這篇文章有簡(jiǎn)單的分析。

Sonwflake 是 Twitter 主鍵生成策略,可以看做是 COMB 的一種改進(jìn),用 64 位的長(zhǎng)整型代替 128 位的字符串。ID 構(gòu)成:第一位 0 + 41 位的時(shí)間前綴 + 10 位的節(jié)點(diǎn)標(biāo)識(shí) + 12 位的 sequence 避免并發(fā)的數(shù)字。

第一部分:Sequence ID


數(shù)據(jù)庫(kù)自增長(zhǎng)序列或字段,最常見(jiàn)的方式。由數(shù)據(jù)庫(kù)維護(hù),數(shù)據(jù)庫(kù)唯一。

優(yōu)點(diǎn):

簡(jiǎn)單,代碼方便,性能可以接受。

數(shù)字 ID 天然排序,對(duì)分頁(yè)或者需要排序的結(jié)果很有幫助。

缺點(diǎn):

不同數(shù)據(jù)庫(kù)語(yǔ)法和實(shí)現(xiàn)不同,數(shù)據(jù)庫(kù)遷移的時(shí)候或多數(shù)據(jù)庫(kù)版本支持的時(shí)候需要處理。

在單個(gè)數(shù)據(jù)庫(kù)或讀寫(xiě)分離或一主多從的情況下,只有一個(gè)主庫(kù)可以生成。有單點(diǎn)故障的風(fēng)險(xiǎn)。

在性能達(dá)不到要求的情況下,比較難于擴(kuò)展。

如果遇見(jiàn)多個(gè)系統(tǒng)需要合并或者涉及到數(shù)據(jù)遷移會(huì)相當(dāng)痛苦。

分表分庫(kù)的時(shí)候會(huì)有麻煩。

優(yōu)化方案:

針對(duì)主庫(kù)單點(diǎn),如果有多個(gè) Master 庫(kù),則每個(gè) Master 庫(kù)設(shè)置的起始數(shù)字不一樣,步長(zhǎng)一樣,可以是 Master 的個(gè)數(shù)。

比如:Master1 生成的是 1,4,7,10,Master2 生成的是 2,5,8,11 Master3 生成的是 3,6,9,12。這樣就可以有效生成集群中的唯一 ID,也可以大大降低 ID 生成數(shù)據(jù)庫(kù)操作的負(fù)載。

第二部分:UUID


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

常見(jiàn)的方式,128 位。可以利用數(shù)據(jù)庫(kù)也可以利用程序生成,一般來(lái)說(shuō)全球唯一。

UUID 是 128 位的全局唯一標(biāo)識(shí)符,通常由 32 字節(jié)的字符串表示。它可以保證時(shí)間和空間的唯一性,也稱為 GUID,全稱為:UUID ―― Universally Unique IDentifier,Python 中叫 UUID。

它通過(guò) MAC 地址、時(shí)間戳、命名空間、隨機(jī)數(shù)、偽隨機(jī)數(shù)來(lái)保證生成 ID 的唯一性。

UUID 主要有五個(gè)算法,也就是五種方法來(lái)實(shí)現(xiàn)。

(1)、uuid1()

――基于時(shí)間戳。由 MAC 地址、當(dāng)前時(shí)間戳、隨機(jī)數(shù)生成??梢员WC全球范圍內(nèi)的唯一性,但 MAC 的使用同時(shí)帶來(lái)安全性問(wèn)題,局域網(wǎng)中可以使用 IP 來(lái)代替 MAC。

(2)、uuid2()

基于分布式計(jì)算環(huán)境 DCE(Python 中沒(méi)有這個(gè)函數(shù))。算法與 uuid1 相同,不同的是把時(shí)間戳的前 4 位置換為 POSIX 的 UID。實(shí)際中很少用到該方法。

(3)、uuid3()

基于名字的 MD5 散列值。通過(guò)計(jì)算名字和命名空間的 MD5 散列值得到,保證了同一命名空間中不同名字的唯一性,和不同命名空間的唯一性,但同一命名空間的同一名字生成相同的 uuid。

(4)、uuid4()

基于隨機(jī)數(shù)。由偽隨機(jī)數(shù)得到,有一定的重復(fù)概率,該概率可以計(jì)算出來(lái)。

(5)、uuid5()

基于名字的 SHA-1 散列值。算法與 uuid3 相同,不同的是使用 Secure Hash Algorithm 1 算法。

優(yōu)點(diǎn):

簡(jiǎn)單,代碼方便。

全球唯一,在遇見(jiàn)數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫(kù)變更等情況下,可以從容應(yīng)對(duì)。

缺點(diǎn):

沒(méi)有排序,無(wú)法保證趨勢(shì)遞增。

UUID 往往是使用字符串存儲(chǔ),查詢的效率比較低。

存儲(chǔ)空間比較大,如果是海量數(shù)據(jù)庫(kù),就需要考慮存儲(chǔ)量的問(wèn)題。

傳輸數(shù)據(jù)量大

不可讀。

優(yōu)化方案:

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

第三部分: GUID


GUID:是微軟對(duì) UUID 這個(gè)標(biāo)準(zhǔn)的實(shí)現(xiàn)。UUID 還有其它各種實(shí)現(xiàn),不止 GUID 一種。優(yōu)缺點(diǎn)同 UUID。

第四部分: COMB


COMB(combine)型是數(shù)據(jù)庫(kù)特有的一種設(shè)計(jì)思想,可以理解為一種改進(jìn)的 GUID,它通過(guò)組合 GUID 和系統(tǒng)時(shí)間,以使其在索引和檢索事有更優(yōu)的性能。

數(shù)據(jù)庫(kù)中沒(méi)有 COMB 類型,它是 Jimmy Nilsson 在他的 “The Cost of GUIDs as Primary Keys” 一文中設(shè)計(jì)出來(lái)的。\

COMB 數(shù)據(jù)類型的基本設(shè)計(jì)思路是這樣的:既然 UniqueIdentifier 數(shù)據(jù)因毫無(wú)規(guī)律可言造成索引效率低下,影響了系統(tǒng)的性能,那么我們能不能通過(guò)組合的方式,保留 UniqueIdentifier 的前 10 個(gè)字節(jié),用后 6 個(gè)字節(jié)表示 GUID 生成的時(shí)間(DateTime),這樣我們將時(shí)間信息與 UniqueIdentifier 組合起來(lái),在保留 UniqueIdentifier 的唯一性的同時(shí)增加了有序性,以此來(lái)提高索引效率。

優(yōu)點(diǎn):

解決 UUID 無(wú)序的問(wèn)題,在其主鍵生成方式中提供了 Comb 算法 (combined guid/timestamp)。保留 GUID 的 10 個(gè)字節(jié),用另 6 個(gè)字節(jié)表示 GUID 生成的時(shí)間 (DateTime)。

性能優(yōu)于 UUID。

第五部分: Twitter 的 snowflake 算法


snowflake 是 Twitter 開(kāi)源的分布式 ID 生成算法,結(jié)果是一個(gè) long 型的 ID。其核心思想是:使用 41bit 作為毫秒數(shù),10bit 作為機(jī)器的 ID(5 個(gè) bit 是數(shù)據(jù)中心,5 個(gè) bit 的機(jī)器 ID),12bit 作為毫秒內(nèi)的流水號(hào)(意味著每個(gè)節(jié)點(diǎn)在每毫秒可以產(chǎn)生 4096 個(gè) ID),最后還有一個(gè)符號(hào)位,永遠(yuǎn)是 0。snowflake 算法可以根據(jù)自身項(xiàng)目的需要進(jìn)行一定的修改。比如估算未來(lái)的數(shù)據(jù)中心個(gè)數(shù),每個(gè)數(shù)據(jù)中心的機(jī)器數(shù)以及統(tǒng)一毫秒可以能的并發(fā)數(shù)來(lái)調(diào)整在算法中所需要的 bit 數(shù)。

優(yōu)點(diǎn):

不依賴于數(shù)據(jù)庫(kù),靈活方便,且性能優(yōu)于數(shù)據(jù)庫(kù)。

ID 按照時(shí)間在單機(jī)上是遞增的。

缺點(diǎn):

在單機(jī)上是遞增的,但是由于涉及到分布式環(huán)境,每臺(tái)機(jī)器上的時(shí)鐘不可能完全同步,也許有時(shí)候也會(huì)出現(xiàn)不是全局遞增的情況。

六、使用

這個(gè)使用起來(lái)是真的方便:

npm install uuid --save

然后就可以使用啦!

  const uuidv1 = require(‘uuid/v1‘);
  console.log(‘隨機(jī)uuid字符串‘, uuidv1());

這樣,我們就可以打印出來(lái) uuid 字符串了。 每次的都不一樣。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI