ULID-分布式系統(tǒng)中生成全局唯一標(biāo)識(shí)符更好的選擇
ULID與UUID
ULID (Universally Unique Lexicographically Sortable Identifier) 是一種用于生成全局唯一標(biāo)識(shí)符的算法。它結(jié)合了時(shí)間戳和隨機(jī)數(shù),以便生成的標(biāo)識(shí)符在排序時(shí)能夠按照時(shí)間順序排列。ULID 的格式為 48 個(gè)字符的字符串,其中包含 10 個(gè)時(shí)間戳字符和 16 個(gè)隨機(jī)數(shù)字符。
ULID 的格式如下:
01AN4Z07BY      79KA1307SR9X4MV3
|----------|    |----------------|
 Timestamp           Randomness
  10 chars           16 charsULID 的時(shí)間戳部分使用當(dāng)前時(shí)間與 Unix Epoch (1970-01-01) 的差值來(lái)表示,而隨機(jī)數(shù)部分則使用隨機(jī)生成的字符來(lái)確保唯一性。
ULID 的設(shè)計(jì)目的是為了在分布式系統(tǒng)中生成全局唯一標(biāo)識(shí)符,并且能夠在數(shù)據(jù)庫(kù)中進(jìn)行排序和索引。
UUID(Universally Unique Identifier)是一種128位的標(biāo)識(shí)符,通常用于唯一標(biāo)識(shí)信息。它是由一組數(shù)字和字母組成的32個(gè)字符的字符串,通常以連字符分隔為五段,形如8-4-4-4-12的格式。UUID的生成算法保證了在所有的時(shí)間和空間中都是唯一的。
在計(jì)算機(jī)科學(xué)中,UUID經(jīng)常用于分布式系統(tǒng)中的唯一標(biāo)識(shí),比如數(shù)據(jù)庫(kù)中的主鍵、消息隊(duì)列中的消息標(biāo)識(shí)等。UUID的唯一性和分散性使得它在分布式系統(tǒng)中具有很高的價(jià)值。
UUID有不同的版本:
- UUIDv1:基于時(shí)間戳和MAC地址生成,可能存在隱私安全風(fēng)險(xiǎn)。
 - UUIDv3:基于名字空間和名稱的MD5散列值生成。
 - UUIDv4:基于隨機(jī)數(shù)生成,具有較高的唯一性。
 - UUIDv5:基于名字空間和名稱的SHA-1散列值生成。
 
每個(gè)版本的UUID都有特定的生成算法和格式要求,用于確保生成的UUID在分布式系統(tǒng)范圍內(nèi)是唯一的。
ULID對(duì)比UUID
ULID是一種用于生成全局唯一標(biāo)識(shí)符的算法,它結(jié)合了時(shí)間戳和隨機(jī)數(shù),以便在分布式系統(tǒng)中生成排序良好的唯一標(biāo)識(shí)符。ULID的格式為26個(gè)字符的字符串,其中包含了時(shí)間戳和隨機(jī)數(shù)。
相比之下,UUID是一種標(biāo)準(zhǔn)化的全局唯一標(biāo)識(shí)符,它通?;陔S機(jī)數(shù)或者基于時(shí)間戳和計(jì)算機(jī)的MAC地址等信息生成。UUID的格式為32個(gè)字符的字符串,通常以32位的十六進(jìn)制數(shù)字表示。
ULID相對(duì)于UUID的優(yōu)勢(shì)在于它是可排序的,因?yàn)樗藭r(shí)間戳信息,這使得在分布式系統(tǒng)中對(duì)生成的標(biāo)識(shí)符進(jìn)行排序和檢索更加高效。而UUID則更加偏向于全局唯一性,但在分布式系統(tǒng)中可能會(huì)存在排序和檢索的性能問(wèn)題。
ULID特性和規(guī)范
- 「全局唯一性」:ULID生成的標(biāo)識(shí)符在全局范圍內(nèi)是唯一的,可以用于標(biāo)識(shí)數(shù)據(jù)記錄、實(shí)體或事件。
 - 「按字典順序可排序」:ULID是按照時(shí)間戳和隨機(jī)數(shù)生成的,因此可以按照字典順序進(jìn)行排序,適合用作數(shù)據(jù)庫(kù)主鍵或索引。
 - 「可讀性」:ULID使用了基于Crockford's Base32的編碼,因此生成的標(biāo)識(shí)符可以以字符串形式呈現(xiàn),并且相對(duì)易讀。
 - 「時(shí)間有序性」:ULID的前部分包含了時(shí)間戳信息,因此可以根據(jù)ULID推斷出生成時(shí)的時(shí)間。
 
ULID的格式通常為01AN4Z07BY,由10位時(shí)間戳和16位隨機(jī)數(shù)組成。其具體生成算法可以參考ULID規(guī)范。
ULID規(guī)范:
- 128位長(zhǎng)度,由時(shí)間戳和隨機(jī)數(shù)組成。
 - 使用時(shí)間戳來(lái)保證排序,使用隨機(jī)數(shù)來(lái)保證唯一性。
 - 采用Crockford's Base32編碼,用于生成可打印的ASCII字符串。
 
ULID的格式如下:
01AN4Z07BY      79KA1307SR9X4MV3
|----------|    |----------------|
 Timestamp           Randomness
   10 chars           16 charsULID的時(shí)間戳部分使用當(dāng)前時(shí)間與Unix紀(jì)元(1970-01-01)的差值來(lái)表示,精確到毫秒級(jí)。隨機(jī)數(shù)部分使用安全的隨機(jī)數(shù)生成算法來(lái)保證唯一性。ULID的設(shè)計(jì)旨在在分布式系統(tǒng)中生成全局唯一標(biāo)識(shí)符,并且可以按時(shí)間排序。
- 時(shí)間戳:占據(jù)前48位,是一個(gè)自增的UTC時(shí)間戳,精確到毫秒。
 - 隨機(jī)數(shù):占據(jù)后80位,使用隨機(jī)數(shù)生成算法生成的隨機(jī)數(shù)。
 
ULID的組成如下:
ULID由32個(gè)可打印字符組成,使用Crockford's Base32編碼表示。具體格式為:
tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt其中,前面的時(shí)間戳部分占據(jù)了前面的48位,后面的隨機(jī)數(shù)部分占據(jù)了后面的80位。
ULID應(yīng)用
ULID通常應(yīng)用于需要生成全局唯一標(biāo)識(shí)符并且需要按時(shí)間排序的各種分布式系統(tǒng)場(chǎng)景,例如:
- 數(shù)據(jù)庫(kù)主鍵:在分布式系統(tǒng)中,可以將ULID作為數(shù)據(jù)庫(kù)表的主鍵,確保每條記錄都有唯一標(biāo)識(shí),并且可以按照生成時(shí)間進(jìn)行排序。
 - 日志跟蹤:在日志系統(tǒng)中,可以使用ULID作為日志條目的唯一標(biāo)識(shí)符,便于跟蹤和排序日志。
 - 分布式系統(tǒng)中的事務(wù)標(biāo)識(shí):在分布式系統(tǒng)中,可以使用ULID作為事務(wù)的唯一標(biāo)識(shí)符,確保每個(gè)事務(wù)都有全局唯一的標(biāo)識(shí)。
 
在Java中使用ULID需要在項(xiàng)目中添加ULID庫(kù)的依賴,可以使用Maven或Gradle進(jìn)行添加。
使用Maven添加ULID庫(kù)的依賴:
<dependency>
    <groupId>de.huxhorn.sulky</groupId>
    <artifactId>de.huxhorn.sulky.ulid</artifactId>
    <version>2.0.0</version>
</dependency>使用Gradle添加ULID庫(kù)的依賴:
implementation 'de.huxhorn.sulky:de.huxhorn.sulky.ulid:2.0.0'添加好ULID庫(kù)的依賴,就可以在Java代碼中使用ULID來(lái)生成唯一標(biāo)識(shí)符。
import de.huxhorn.sulky.ulid.ULID;
public class Main {
    public static void main(String[] args) {
        ULID.Value ulid = new ULID().nextValue();
        System.out.println(ulid);
    }
}














 
 
 










 
 
 
 