UUID的方式能生成一串惟一隨機32位長度數據,它是無序的一串數據,按照開放軟件基金會(OSF)制定的標準計算,UUID的生成用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字。UUID的底層是由一組32位數的16進制數字構成,是故 UUID 理論上的總數爲html
UUID 的十六個八位字節被表示爲 32個十六進制數字,以連字號分隔的五組來顯示,形式爲 8-4-4-4-12,總共有 36個字符(即三十二個英數字母和四個連字號)。例如:java
123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
複製代碼
上面的以數字 M開頭的四位表示 UUID 版本,目前UUID的規範有5個版本,M可選值爲1, 2, 3, 4, 5 ;各個版本的具體介紹以下所示:mysql
version 1:0001。基於時間和 MAC 地址。因爲使用了 MAC 地址,所以可以確保惟一性,可是同時也暴露了 MAC 地址,私密性不夠好。 version 2:0010。DCE 安全的 UUID。該版本在規範中並無仔細說明,所以並無具體的實現。 version 3:0011。基於名字空間 (MD5)。用戶指定一個名字空間和一個字符串,經過 MD5 散列,生成 UUID。字符串自己須要是惟一的。 version 4:0100。基於隨機數。雖然是基於隨機數,可是重複的可能性能夠忽略不計,所以該版本也是被常用的版本。 version 5:0101。基於名字空間 (SHA1)。跟 Version 3 相似,可是散列函數編程了 SHA1。算法
上面以數字 N開頭的四個位表示 UUID 變體( variant ),變體是爲了能兼容過去的 UUID,以及應對將來的變化,目前已知的變體有以下幾種,由於目前正在使用的 UUID 都是 variant1,因此取值只能是 8,9,a,b 中的一個(分別對應1000,1001,1010,1011)。sql
variant 0:0xxx。爲了向後兼容預留。 variant 1:10xx。當前正在使用的。 variant 2:11xx。爲早期微軟 GUID 預留。 variant 3:111x。爲未來擴展預留。目前暫未使用。數據庫
Java已經寫好一個UUID類供咱們使用,以下所示編程
package com.one.util;
import java.util.UUID;
public class Test {
public static void main(String[] args) {
String uuid= UUID.randomUUID().toString().replace("-", "").toLowerCase();
System.out.println(uuid);
}
}
複製代碼
結果以下所示 segmentfault
若是需求是隻保證惟一性,那麼UUID也是可使用的,可是按照上面的分佈式id的要求, UUID實際上是不能作成分佈式id的,緣由以下:安全
- 首先分佈式id通常都會做爲主鍵,可是安裝mysql官方推薦主鍵要儘可能越短越好,UUID每個都很長,因此不是很推薦
- 既然分佈式id是主鍵,而後主鍵是包含索引的,而後mysql的索引是經過b+樹來實現的,每一次新的UUID數據的插入,爲了查詢的優化,都會對索引底層的b+樹進行修改,由於UUID數據是無序的,因此每一次UUID數據的插入都會對主鍵地城的b+樹進行很大的修改,這一點很很差
- 信息不安全:基於MAC地址生成UUID的算法可能會形成MAC地址泄露,這個漏洞曾被用於尋找梅麗莎病毒的製做者位置。
好比阿里雲每一條短信發送的惟一id,這個是能夠的,好比從阿里雲官網截圖所示: dom
分佈式ID其餘系列快捷鍵:
分佈式ID系列(1)——爲何須要分佈式ID以及分佈式ID的業務需求
分佈式ID系列(3)——數據庫自增ID機制適合作分佈式ID嗎
分佈式ID系列(4)——Redis集羣實現的分佈式ID適合作分佈式ID嗎
分佈式ID系列(5)——Twitter的雪法算法Snowflake適合作分佈式ID嗎