PhotobyMarkusSpiskeonUnsplash通用唯一標識符(UUID)是一個128位數字,用于標識計算機系統中的信息。它也被稱為全局唯一標">

操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    看通用唯一標識符

    > Photo by Markus Spiske on Unsplash

    通用唯一標識符(UUID)是一個128位數字,用于標識計算機系統中的信息。 它也被稱為全局唯一標識符(GUID)。 UUID的標準表示形式通常由十六進制數字組成:

    e5d520d8-d06e-4bc2-9bb9-a28e47014884

    總共可以看到32個字符,中間有四個連字符。 為了不辜負他們的名字,UUID應該是唯一的。 實際上,通常情況并非如此-它們的唯一性取決于生成它們的方法或算法。 但是,雖然有可能,但是復制UUID的可能性足夠接近零,可以忽略不計。

    有多種計算UUID的方法。 我將解釋差異是什么,并提供一些實現的見解。

    版本一

    第一個版本的UUID是使用計算機的MAC地址和生成時間生成的通用唯一標識符。

    這是否意味著一個UUID版本是完全唯一的? 好吧,他們差不多。 確保唯一性的計算機(或節點)每秒限制為1630億,但這并不是開發人員經常遇到的問題。

    此版本還有其他問題要擔心。 幾乎可以保證的唯一性是以匿名為代價的。 由于此版本需要考慮時間和唯一的MAC地址,因此可以確定計算機的地址和時間。

    版本二

    我將簡短地討論第二版。 實際上,第二版UUID與第一版相似,并且由于RFC 4122并未提供太多詳細信息而很少實現。 實際上,您根本不會使用它們。 它們也稱為DCE安全性UUID。

    版本三

    在第三版中,使用加密哈希和應用程序提供的文本字符串來生成UUID。 在此版本中,使用MD5哈希。 基本上,UUID是根據名稱生成的。 現在,我們可以使用名稱和名稱空間來創建一系列UUID。 MD5哈希算法是一種廣泛使用的哈希函數,可產生128位哈希值。

    最初,MD5被設計為用作加密哈希函數,但現在似乎存在漏洞問題。 找到兩條散列為相同值的不同消息太容易了。 因此,它不是您要在應用程序中使用的版本。

    版本四

    偽隨機數生成器,也稱為確定性隨機位生成器,是一種用于生成數字序列的算法,該數字序列的屬性近似于隨機數序列的屬性。 —維基百科

    此版本使用偽隨機數生成器生成UUID。 使用非常簡單。 字符串的每一位都是完全"隨機"生成的。 UUID仍然有可能被復制,但由于可能的組合數量很多,所以它很小。 確切的可能性數約為2 12?。

    到今天為止,第四版已采用大多數編程語言實現。 它非常易于使用。 我將用Java舉例:

    UUID uuid=UUID.randomUUID();

    版本五

    版本3和版本5之間的唯一區別是使用了不同的哈希算法。 第五版使用SHA-1而不是MD5。 從技術上講,它是一種出色的哈希算法,但它也可能遇到與第三版相同的問題。 我不建議使用它。


    盡管幾乎每個版本都有其長處,但它們也有明顯的弱點,可能會損害您的應用程序設計。

    第四版是完全隨機的,基本上是不可預測的,這是我建議現在使用的版本。

    如果您不想在多個數據庫實例上發生沖突,或者您不想讓ID可預測或提供有關系統的信息,請考慮使用UUID。


    結論

    UUID的最大好處是,它實際上是唯一的(與保證唯一性相反),對于日常使用來說仍然是完全可以接受的。

    這是UUID的主要缺點:

    · 例如,無需使用每次在數據庫中插入記錄時都會增加的索引,而是需要生成UUID。 這可能需要更長的時間。 它沒有說明創建的順序。 如果您需要訂購,請考慮不使用UUID對標識符以外的其他東西進行排序。

    · 與他們一起工作可能有些奇怪。 UUID也沒有說任何有關其所屬實體的信息。 這會使調試變得更加困難,尤其是在測試中。

    · 該值相當長,可能會影響性能。 但是,如今這些空間更便宜了。

    但這也有一些重要的好處:

    · UUID的主要優點是它是唯一的。 例如,用戶幾乎不可能將其猜測為URL參數(公開討論,因為這可能是安全問題)。 它們在應用程序中是唯一的。

    · 它與環境無關。 您可以在任何地方(甚至離線)生成它,而無需依賴數據庫來生成標識符。 如果您有多個包含一個數據段(碎片)的數據庫,則UUID在所有數據庫中都是唯一的,而不僅僅是您現在所在的那個。 這使得在數據庫之間移動數據更加安全。


    (本文翻譯自Dieter Jordens的文章《What Is a UUID and How Are They Generated?》,參考:https://medium.com/better-programming/what-is-a-uuid-and-how-are-they-generated-17f0acbd7233)

    UID 的全稱是 Universally Unique Identifier,中文為通用唯一識別碼。

    在對 UUID 進行說明之前,我們來看一個標準的 UUID。

    下面就是一個標準的 UUID,使用橫杠分隔符來進行分隔:

    123e4567-e89b-42d3-a456-556642440000
    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
    

    UUID 結構有關版本的定義

    在結構中的 M,定義了 UUID 的版本,UUID 的 5 個版本就是在這里進行定義的。

    Version 1 (基于時間)

    這個版本是基于隨機數的,使用的基數為每 100 納秒為一個單位,時間的起點為1582年10月15日。同時還需要加上當前計算機的網卡物理地址(MAC)。

    Version 2 (DCE – 分布式計算機環境):

    UUID-v2 和V1 很類似,是根據標識符(通常是組或用戶ID )、時間和節點ID 生成,不過區別在于V2 將V1 中的部分時間信息換成了主機名, 故應用具有局限性(有隱私風險),未大規模使用。

    Version 3 (基于命名)

    UUID-v3 通過散列(MD5 )名字空間(namespace )標識符和名稱生成。和V1 、V2 不同,V3 不依賴與機器信息和時間信息, 但是V3 要求輸入命名空間+名稱,命名空間本身也是一個UUID ,用來標識應用環境,名稱通常是用戶賬號、用戶名之類的內容,通過命名空間+名稱+三列算法算出UUID 。

    Version 4 (基于隨機數)

    UUID-v4 組成 UUID v4 的位是隨機生成的,沒有固有邏輯(除了第三段首個數字,該數字標識版本號),不包含命名空間、設備信息、時間信息。 故,UUID-v4 最容易理解、應用也最為廣泛。

    Version 5 (基于使用 SHA-1 的命名)

    UUID-v5 和V3 類似,區別在于散列算法,使用了sha1 散列算法。
    可以認為 UUIDv5 就是為了強化 UUIDv3 出現的問題而使用新的哈希算法。


    . UUID 是什么?

    UUID(Universally Unique Identifier 通用唯一識別碼)用于標識資源唯一性。理論上說,門牌號、電話號碼、郵編、身份證號都是用來標識資源唯一性的,但為使用方便,不適合用一個無規律的字符串表示,UUID 主要還是在程序中使用。

    UUID 源自1980年代的 Apollo 電腦公司,是一個 128 位的標識符,理論上的總數有 2128個,也就是說,哪怕每納秒產生 1 萬億個 UUID,也要 100 億年才能用完。因此,只要保證生成方法的散布足夠好,統計概率上,UUID 重復的可能性約等于 0 。

    UUID 的具體規范可以參考 RFC 4122。這個標準定義了 5 個版本的 UUID:

    1. 版本 1 根據時間和 MAC 地址來生成 UUID。MAC 地址用于保證設備唯一性。通過在時間戳后加入 13-14 位的時鐘序列,可以保證在同一臺設備,同 1 秒內生成的 1630 億個 UUID 不重復。 這個版本的 UUID 我們用得相對較少,一個原因是其中攜帶了設備信息。1999 年,著名病毒梅麗莎的作者,因為代碼中的 UUID 暴露了 MAC 地址信息,不到一個星期就被抓住了。另一個原因是這個版本的 UUID 生成有規律,比較容易根據一個 UUID 推斷到下一個 UUID。
    2. 版本 2 是一個 DEC 安全的版本,RFC4122 中也沒有詳細說明具體實現方式,我們一般也用不到。
    3. 版本 3 根據字符串和命名空間散列值(HASH)來獲取 UUID。由于 HASH 函數本身的特性,一般不用擔心 UUID 沖突,或者別人根據散列值反推原數據的問題。這個版本采用的是 MD5 散列值。
    4. 版本 4 根據隨機數生成 UUID,是我們比較常用的版本。
    5. 版本 5 和版本 3 一樣,也是根據散列值獲取 UUID,不過采用的散列算法是 SHA-1 而不是 MD5,相較而言,RFC4122 推薦大家使用版本 5 而不是版本 3。

    我們常看到的 UUID 往往被表示為 16 進制數字和橫杠組成的字符串,比如:a3535b78-69dd-4a9e-9a79-57e2ea28981b,其中第二個橫杠之后的第一個數字表示 UUID 版本,例子中這個 UUID 就是版本 4 的。


    2. 為什么在數據庫中使用 UUID?

    大多數人在數據庫中存儲 UUID 的直接原因,是需要一個不暴露內部信息的唯一標識。例如博客文章,Title 無法保證不重復,數字 ID 則會暴露內部信息,于是,可以生成一個 UUID 作為唯一標識。類似地,我們在網上請求的許多公開資源,如圖片、音頻、以及其他文件等,都是以 UUID 作為標識的。

    第二個原因,是為了方便數據管理:

    1. 當數據量過大,不得不進行分片管理的時候,數字 ID 的唯一性不好保證;萬一需要重建部分數據,數字 ID 也很難確保與原表一致。
    2. UUID 作為預先生成的值,可以在插入數據庫之前拿到,會方便一些數據操作。

    3. UUID 作為主鍵有什么問題?

    一般不推薦把 UUID 作為主鍵,它會帶來不少問題:

    3.1 數據碎片化

    我們知道,使用自增 ID 作為主鍵時,插入新的數據行往往是連續的,插入多條數據只需要讀寫少數數據頁。但由于 UUID 的隨機性,新插入的數據往往會落在不同的數據頁上,導致數據碎片化,同樣的數據量,可能需要更大的空間才能存儲。

    同時,當數據量上升,內存中無法暫存足夠多的數據頁時,每次插入數據都可能涉及硬盤讀寫,極大地拖慢了數據插入效率。

    3.2 索引占用空間過大

    大多數人會把 UUID 保存為 16 進制數字和橫杠組成的字符串,也就是 char(36),如果采用 UTF-8 字符集,它所占的字節數是 2 + 3 * 36=110 字節(前面 2 個字節為長度,后面每個字符 3 個字節)。相較而言,一個整數只有 4 個字節,相差 27 倍。

    數據庫采用 B 樹索引,其中主鍵索引的葉子節點指向數據行,而二級索引的葉子節點存儲著主鍵,之后再通過主鍵索引回表查數據。也就是說,有多少個二級索引,主鍵就需要被存儲幾次,因此,索引的空間需求就極速擴張了。

    在數據庫運行過程中,為加快查詢速度,這些索引往往需要被加載到內存中。那么,過大的索引導致內存不足,就會嚴重影響數據庫查詢效率。

    3.3 字符比較比整數比較慢

    CPU 每次最多可以比較 8 個字節的整數值,但對于字符串,必須一個字符一個字符比較過去。有測試說明,在查詢比較時,使用整數的速度比使用字符串的速度快數倍到數十倍之間。

    不過,一般來說,數據庫不是一個 CPU 密集的應用,因此這方面的影響不是主要考慮因素。


    4. 替代方案討論

    4.1 優化 UUID 的存儲

    將 UUID 存儲為 16 進制值和橫杠組成的字符串是非常低效的,UUID 本身只有 128 位,也就是 16 字節,存儲成字符串后卻有 110 個字節,膨脹了 7 倍,憑空多占了不少空間。優化的思路就是采用更好的格式,比如直接存儲二進制,或者將二進制值存儲為 base64 字符串。相對復雜一點的是將 UUID 映射到一個整數。

    優化存儲格式的具體實現都不困難,也能相當程度地節約存儲空間,但并沒有解決 UUID 的隨機性帶來的數據碎片化的問題。

    針對碎片化的問題,有一個思路是控制隨機性,也就是增加一個自己生成的字符串作為前綴,比如說日期(或它的哈希值)。因為字符串排序從前往后走,同樣的前綴也就意味著接近的排序,那么,原本散布在整個數據庫的值,就會集中分布在一定范圍內的數據頁,從而大大緩解了內存壓力。

    4.2 同時使用自增 ID 和 UUID

    更常見的思路,是使用自增 ID 作為主鍵,同時使用 UUID 作為唯一標識和與其它表關聯的外鍵。好處是有了一個可以比較安全地對外暴露的唯一標識,節約了索引空間,也不用擔心數據分片和數據重建帶來的危險。

    但也存在一些問題,因為所有的外鍵關聯都用的 UUID,所以占用的空間自然會大一些,同時,字符串比較速度較慢和所有查詢都要回表也是值得考慮的因素。

    4.3 避開 UUID

    很多小型應用不需要考慮數據管理的問題,只是需要一個可以對外暴露的唯一標識,于是,干脆放棄 UUID,采用其他思路實現標識的唯一性。

    比如說前面說的博客文章,鑒于 Title 沒法保證唯一性,可以在 Title 前后加上一個前綴或者后綴,從而實現唯一性。一個思路是使用隨機字符串,或者作者、日期等信息。

    又比如說,將每個數據行映射到一個大整數作為唯一標識。某種意義上等于根據自己的實際需要寫了一套新的唯一標識算法。


    END

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有