新聞中心
1. UUID
UUID是可以生成時間、空間上都獨一無二的值,其本質(zhì)是隨機(jī)+規(guī)則組合而成的。即使在兩個獨立的服務(wù)器上生成UUID,其預(yù)期值也是不同的。以MySQL為例,說明下UUID。

站在用戶的角度思考問題,與客戶深入溝通,找到黎城網(wǎng)站設(shè)計與黎城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋黎城地區(qū)。
格式
在MySQL中,UUID值是一個128位的數(shù)字,表示為以下格式的十六進(jìn)制數(shù)字的utf8字符串:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee。其得到的隨機(jī)值由5個部分組成,且分隔符位為:中劃線。其各部分含義如下:
- 前三組值是時間戳換算過來的;?
- 第四組值是暫時性保持時間戳的唯一性。例如,使用夏令時;
- 第五組值是一個IEE 802的節(jié)點標(biāo)識值,它是空間上唯一的。若后者不可用,則用一個隨機(jī)數(shù)字替換。假如主機(jī)沒有網(wǎng)卡,或者我們不知道如何在某系統(tǒng)下獲得機(jī)器地址,則空間唯一性就不能得到保證,即使這樣出現(xiàn)重復(fù)值的幾率還是非常小的。
在MySQL環(huán)境中多次調(diào)用或執(zhí)行得到的后兩組值相同,若把mysqld服務(wù)器關(guān)閉,重新啟動之后,會發(fā)現(xiàn)第四組的組與未重啟前的值發(fā)生變化,然后一直不變化,只要重新啟動mysqld服務(wù)就會發(fā)生變化。另外,對于同一臺機(jī)器,第五組值始終不會發(fā)生變化。
優(yōu)點
使用UUID作為主鍵具有以下優(yōu)點:
- UUID值在表,數(shù)據(jù)庫甚至在服務(wù)器上都是唯一的,允許您從不同數(shù)據(jù)庫合并行或跨服務(wù)器分發(fā)數(shù)據(jù)庫。
- UUID值不會公開有關(guān)數(shù)據(jù)的信息,因此在URL中使用更安全。
- 可以在避免往返數(shù)據(jù)庫服務(wù)器的任何地方生成UUID值。它也簡化了應(yīng)用程序中的邏輯。
缺點
除了優(yōu)勢之外,UUID值也存在一些缺點:
- 存儲UUID值(16字節(jié))比整數(shù)(4字節(jié))或甚至大整數(shù)(8字節(jié))占用更多的存儲空間。
- 調(diào)試似乎更加困難,想象一下WHERE id ='9d6212cf-72fc-11e7-bdf0-f0def1e6646c'和WHERE id = 10哪個舒服一點?
- 使用UUID值可能會導(dǎo)致性能問題,因為它們的大小和沒有被排序。
數(shù)據(jù)庫案例:MySQL
在MySQL中,就內(nèi)置了對UUID的支持。在使用上需注意若干問題。
- 作為主鍵問題
UUID()函數(shù)產(chǎn)生的值,并不適合作為InnoDB引擎表的主鍵。因為格式無序,作為索引組織表存儲會帶來管理上的不小開銷。
- 格式問題
在MySQL中,可以使用UUID()來生成主鍵,但是用MySQL的UUID()函數(shù) ,生成的UUID是36位的,其中包含32個字符以及4個分隔符(-),往往這個分隔符對我們來說是沒有用的,可以使用MySQL自帶的REPLACE函數(shù)去掉分隔符。
- 內(nèi)置函數(shù)
支持在MySQL中,可以以緊湊格式(BINARY)存儲UUID值,并通過以下功能顯示人機(jī)可讀格式(VARCHAR):UUID_TO_BIN、BIN_TO_UUID、IS_UUID。需要注意,UUID_TO_BIN(),BIN_TO_UUID()和IS_UUID()函數(shù)僅在MySQL 8.0或更高版本中可用。- UUID_TO_BIN()函數(shù)將UUID從人類可讀格式(VARCHAR)轉(zhuǎn)換成用于存儲的緊湊格式(BINARY)格式- BIN_TO_UUID()函數(shù)將UUID從緊湊格式(BINARY)轉(zhuǎn)換為人類可讀格式(VARCHAR)- IS_UUID()函數(shù)則可用來判斷參數(shù)是有效的字符串格式UUID。
2. NanoID
UUID 是軟件開發(fā)中最常用的通用標(biāo)識符之一。然而,在過去的幾年里,其他的競品挑戰(zhàn)了它的存在。其中,NanoID 是 UUID 的主要競爭對手之一。但是,這兩者之間的主要區(qū)別很簡單。它歸結(jié)為鍵所使用的字母表。由于 NanoID 使用比 UUID 更大的字母表,因此較短的 ID 可以用于與較長的 UUID 相同的目的。
優(yōu)點
- 更小
NanoID 只有 108 個字節(jié)那么大。與 UUID 不同,NanoID 的大小要小 4.5 倍,并且沒有任何依賴關(guān)系。此外,大小限制已用于將大小從另外 35% 減小。大小減少直接影響數(shù)據(jù)的大小。例如,使用 NanoID 的對象小而緊湊,能夠用于數(shù)據(jù)傳輸和存儲。隨著應(yīng)用程序的增長,這些數(shù)字變得明顯起來。
- 更安全
在大多數(shù)隨機(jī)生成器中,它們使用不安全的 Math.random()。但是,NanoID 使用 crypto module 和 Web Crypto API,意味著 NanoID 更安全。此外,NanoID 在 ID 生成器的實現(xiàn)過程中使用了自己的算法,稱為 統(tǒng)一算法,而不是使用“隨機(jī) % 字母表” random % alphabet。
- 更快
NanoID既快速又緊湊,NanoID 比 UUID 快 60%。與 UUID 字母表中的 36 個字符不同,NanoID 只有 21 個字符。
- 更多語言
NanoID 支持 14 種不同的編程語言,它們分別是:C#、C++、Clojure 和 ClojureScript、Crystal、Dart & Flutter、Deno、Go、Elixir、Haskell、Janet、Java、Nim、Perl、PHP、帶字典的 Python、Ruby、Rust、Swift。
- 更好兼容性
它還支持 PouchDB、CouchDB WebWorkers、Rollup 以及 React 和 Reach-Native 等庫。我們可以使用 npx nanoid 在終端中獲得唯一 ID。在 JavaScript 中使用 NanoID 唯一的要求是要先安裝 NodeJS。
- 自定義字母
NanoID 的另一個現(xiàn)有功能是它允許開發(fā)人員使用自定義字母表。我們可以更改文字或 id 的大小。在下面的示例中,我將自定義字母表定義為 ABCDEF1234567890,并將 Id 的大小定義為 12。
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('ABCDEF1234567890', 12);
model.id = nanoid();- 沒有第三方依賴
由于 NanoID 不依賴任何第三方依賴,隨著時間的推移,它能夠變得更加穩(wěn)定自治。從長遠(yuǎn)來看,這有利于優(yōu)化包的大小,并使其不太容易出現(xiàn)依賴項帶來的問題。
數(shù)據(jù)庫案例-ShardingSphere
原生數(shù)據(jù)庫產(chǎn)品,大多沒有支持NanoID,但可通過外部方式引用進(jìn)來。例如在開源項目 Apache ShardingSphere 中可通過規(guī)則的配置,在其分片表中使用 NanoID作為主鍵生成器。參考如下配置:
CREATE SHARDING TABLE RULE t_order(
RESOURCES(ds_3307,ds_3308),
SHARDING_COLUMN=order_id,TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME=NanoID,PROPERTIES("worker-id"=123)))
);
CREATE TABLE t_order (
user_id int NOT NULL,
status varchar(50) DEFAULT NULL,
PRIMARY KEY (order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. SnowFlake
分布式系統(tǒng)中ID生成方案,比較簡單的是UUID(Universally Unique Identifier,通用唯一識別碼),但是其存在兩個明顯的弊端:一、UUID是128位的,長度過長;二、UUID是完全隨機(jī)的,無法生成遞增有序的UUID。而現(xiàn)在流行的基于 Snowflake 雪花算法的ID生成方案就可以很好地解決了UUID存在的這兩個問題。
原理
Snowflake 雪花算法,由Twitter提出并開源,可在分布式環(huán)境下用于生成唯一ID的算法。該算法生成的是一個64位的ID。在同一個進(jìn)程中,它首先是通過時間位保證不重復(fù),如果時間相同則是通過序列位保證。同時由于時間位是單調(diào)遞增的,且各個服務(wù)器如果大體做了時間同步,那么生成的主鍵在分布式環(huán)境可以認(rèn)為是總體有序的,這就保證了對索引字段的插入的高效性。例如 MySQL 的 Innodb 存儲引擎的主鍵。
格式
使用雪花算法生成的主鍵,二進(jìn)制表示形式包含 4 部分,從高位到低位分表為:1bit 符號位、41bit 時間戳位、10bit 工作進(jìn)程位以及 12bit 序列號位。
- 符號位(1bit)
預(yù)留的符號位,恒為零。
- 時間戳位(41bit)
41 位的時間戳可以容納的毫秒數(shù)是 2 的 41 次冪,一年所使用的毫秒數(shù)是:365 * 24 * 60 * 60 * 1000。通過計算可知:Math.pow(2, 41) / (365 * 24 * 60 * 60 * 1000L); 結(jié)果約等于 69.73 年。Apache ShardingSphere 的雪花算法的時間紀(jì)元從 2016 年 11 月 1 日零點開 始,可以使用到 2086 年,相信能滿足絕大部分系統(tǒng)的要求。
- 工作進(jìn)程位(10bit)
該標(biāo)志在 Java 進(jìn)程內(nèi)是唯一的,如果是分布式應(yīng)用部署應(yīng)保證每個工作進(jìn)程的 id 是不同的。該值默認(rèn)為0,可通過屬性設(shè)置。
- 序列號位(12bit)
該序列是用來在同一個毫秒內(nèi)生成不同的 ID。如果在這個毫秒內(nèi)生成的數(shù)量超過 4096 (2 的 12 次冪),那么生成器會等待到下個毫秒繼續(xù)生成。
優(yōu)點
使用SnowFlake的優(yōu)點是其空間占用更小,且具備一定有序性,這對于類似MySQL數(shù)據(jù)庫是比較友好的。
缺點
因為其生成策略需參考當(dāng)前時間,當(dāng)服務(wù)器時鐘回?fù)軙?dǎo)致產(chǎn)生重復(fù)序列,因此默認(rèn)分布式主鍵生成器提供了一個最大容忍的時鐘回?fù)芎撩霐?shù)。如果時鐘回?fù)艿臅r間超過最大容忍的毫秒數(shù)閾值,則程序報錯;如果在可容忍的范圍內(nèi),默認(rèn)分布式主鍵生成器會等待時鐘同步到最后一次主鍵生成的時間后再繼續(xù)工作。最大容忍的時鐘回?fù)芎撩霐?shù)的默認(rèn)值為 0,可通過屬性設(shè)置。
數(shù)據(jù)庫案例-ShardingSphere
原生數(shù)據(jù)庫產(chǎn)品,大多沒有支持SnowFlake,但可通過外部方式引用進(jìn)來。例如在開源項目 Apache ShardingSphere 中可通過規(guī)則的配置,在其分片表中使用 SnowFlake作為主鍵生成器。參考如下配置
CREATE SHARDING TABLE RULE t_order(
RESOURCES(ds_3307,ds_3308),
SHARDING_COLUMN=order_id,TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME= Snowflake,PROPERTIES("worker-id"=123)))
);
CREATE TABLE t_order (
order_id varchar(50) NOT NULL,
user_id int NOT NULL,
status varchar(50) DEFAULT NULL,
PRIMARY KEY (order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
作者介紹
韓鋒,社區(qū)編輯,CCIA(中國計算機(jī)協(xié)會)常務(wù)理事,前Oracle?ACE,騰訊TVP,阿里云MVP,dbaplus等多家社群創(chuàng)始人或?qū)<覉F(tuán)成員。有著豐富的一線數(shù)據(jù)庫架構(gòu)、軟件研發(fā)、產(chǎn)品設(shè)計、團(tuán)隊管理經(jīng)驗。曾擔(dān)任多家公司首席DBA、數(shù)據(jù)庫架構(gòu)師等職。在云、電商、金融、互聯(lián)網(wǎng)等行業(yè)均有涉獵,精通多種關(guān)系型數(shù)據(jù)庫,對NoSQL及大數(shù)據(jù)相關(guān)技術(shù)也有涉足,實踐經(jīng)驗豐富。曾著有數(shù)據(jù)庫相關(guān)著作《SQL優(yōu)化最佳實踐》、《數(shù)據(jù)庫高效優(yōu)化》。
文章名稱:淺談幾種常見的分布式ID
文章路徑:http://www.fisionsoft.com.cn/article/coosjsd.html


咨詢
建站咨詢
