什么是數(shù)據(jù)庫(kù)主鍵 ID 生成策略?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
我們提供的服務(wù)有:網(wǎng)站建設(shè)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、二道ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的二道網(wǎng)站制作公司前言:
系統(tǒng)唯一 ID 是我們?cè)谠O(shè)計(jì)一個(gè)系統(tǒng)的時(shí)候常常會(huì)遇見的問題,下面介紹一些常見的 ID 生成策略。
● Sequence ID
● UUID
● GUID
● COMB
● Snowflake
最開始的自增 ID 為了實(shí)現(xiàn)分庫(kù)分別的需求,會(huì)在自增的前提下,使用不同起點(diǎn),但需要做數(shù)據(jù)庫(kù)拓展時(shí),極其麻煩。 比如剛開始時(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。。。 但是這樣的問題就是,如果有一天我發(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)序列或字段,最常見的方式。由數(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ù)或讀寫分離或一主多從的情況下,只有一個(gè)主庫(kù)可以生成。有單點(diǎn)故障的風(fēng)險(xiǎn)。
在性能達(dá)不到要求的情況下,比較難于擴(kuò)展。
如果遇見多個(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
常見的方式,128 位??梢岳脭?shù)據(jù)庫(kù)也可以利用程序生成,一般來(lái)說全球唯一。
UUID 是 128 位的全局唯一標(biāo)識(shí)符,通常由 32 字節(jié)的字符串表示。它可以保證時(shí)間和空間的唯一性,也稱為 GUID,全稱為:UUID ―― Universally Unique IDentifier,Python 中叫 UUID。
它通過 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ǎng)中可以使用 IP 來(lái)代替 MAC。
(2)、uuid2()
基于分布式計(jì)算環(huán)境 DCE(Python 中沒有這個(gè)函數(shù))。算法與 uuid1 相同,不同的是把時(shí)間戳的前 4 位置換為 POSIX 的 UID。實(shí)際中很少用到該方法。
(3)、uuid3()
基于名字的 MD5 散列值。通過計(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)單,代碼方便。
全球唯一,在遇見數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫(kù)變更等情況下,可以從容應(yīng)對(duì)。
缺點(diǎn):
沒有排序,無(wú)法保證趨勢(shì)遞增。
UUID 往往是使用字符串存儲(chǔ),查詢的效率比較低。
存儲(chǔ)空間比較大,如果是海量數(shù)據(jù)庫(kù),就需要考慮存儲(chǔ)量的問題。
傳輸數(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,它通過組合 GUID 和系統(tǒng)時(shí)間,以使其在索引和檢索事有更優(yōu)的性能。
數(shù)據(jù)庫(kù)中沒有 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)的性能,那么我們能不能通過組合的方式,保留 UniqueIdentifier 的前 10 個(gè)字節(jié),用后 6 個(gè)字節(jié)表示 GUID 生成的時(shí)間(DateTime),這樣我們將時(shí)間信息與 UniqueIdentifier 組合起來(lái),在保留 UniqueIdentifier 的唯一性的同時(shí)增加了有序性,以此來(lái)提高索引效率。
優(yōu)點(diǎn):
解決 UUID 無(wú)序的問題,在其主鍵生成方式中提供了 Comb 算法 (combined guid/timestamp)。保留 GUID 的 10 個(gè)字節(jié),用另 6 個(gè)字節(jié)表示 GUID 生成的時(shí)間 (DateTime)。
性能優(yōu)于 UUID。
第五部分: Twitter 的 snowflake 算法
snowflake 是 Twitter 開源的分布式 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)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)建站的支持。