zoukankan      html  css  js  c++  java
  • UUID

    什么是UUID?

    通用唯一识别码Universally Unique Identifier,缩写:UUID)是用于让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID,就不需考虑数据库创建时的名称重复问题还有相关的术语:全局唯一标识符(GUID)。

    版本

    • version 1, date-time & MAC address(时间戳和MAC地址)

    • version 2, date-time & group/user id (时间戳和组或用户ID)

    • version 3, MD5 hash & namespace (散列(hashing)命名空间和名称)

    • version 4, pseudo-random number ((伪)随机数)

    • version 5, SHA-1 hash & namespace (散列(hashing)命名空间和名称)

    版本3使用 MD5 作为散列算法,版本5使用 SHA1。推荐版本5(SHA1)而不是版本3(MD5),建议不要使用任一版本的 UUID 作为安全凭证。这5个版本使用不同算法,利用不同的信息来产生UUID,各版本有各自优势,适用于不同情景。

    定义

    UUID是由一组32位数的16进制数字所构成,故UUID理论上的总数为16^32 = 2^128,约等于3.4 x 10^38。也就是说若每纳秒(ns)产生1个UUID,要花100亿年才会将所有UUID用完。

    UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为 8-4-4-4-12 的32个字符。示例:

    550e8400-e29b-41d4-a716-446655440000

    格式

    UUID "8-4-4-4-12" 形式中总共 36 个字符(32 个字母数字字符和 4 个连字符)。例如:

    123e4567-e89b-12d3-a456-426655440000

    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

    M表示 UUID 版本,N的一至三个最高有效位表示 UUID 变体。在例子中,M1 而且 Na10xx),这意味着此 UUID 是“版本1”、“变体1”UUID;即基于时间的 DCE/RFC 4122 UUID。

    碰撞

    在 103 万亿 个 版本4 UUID 中找到重复的概率是 1/1000000000 十亿分之一。

    产生重复 UUID 并造成错误的情况非常低,大可不必考虑此问题。

    作为数据库主键

    UUID 在数据库用的应用

    在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库自生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。
    UUID作主键是最简单的方案,本地生成,性能高,没有网络耗时。但缺点也很明显,由于UUID非常长,会占用大量的存储空间;另外,作为主键建立索引和基于索引进行查询时都会存在性能问题,在InnoDB下,UUID的无序性会引起数据位置频繁变动,导致分页。

    MySQL 提供了一个 UUID() 函数,它生成标准 版本1 UUID。

    PostgreSQL 包含一个 UUID 数据类型,并且可以通过使用模块中的函数生成大多数版本的UUID。

    Snowflake(雪花数)分布式自增ID算法

    是一个19位的正整数。

    Twitter的snowflake算法解决了分布式系统生成全局ID的需求,生成64位的Long型数字,组成部分:

    • 第一位未使用
    • 接下来41位是毫秒级时间,41位的长度可以表示69年的时间
    • 5位datacenterId,5位workerId。10位的长度最多支持部署1024个节点
    • 最后12位是毫秒内的计数,12位的计数顺序号支持每个节点每毫秒产生4096个ID序列

    这样的好处是:毫秒数在高位,生成的ID整体上按时间趋势递增;不依赖第三方系统,稳定性和效率较高,理论上QPS约为409.6w/s(1000*2^12),并且整个分布式系统内不会产生ID碰撞;可根据自身业务灵活分配bit位。

    不足:依赖机器时钟,如果时钟回拨,则可能导致生成ID重复。

    综上

    UUID和雪花数相比,UUID长度比较长,占用的存储空间比雪花数大,且雪花数是基本有序的,所以雪花数更合适用作分布式系统ID。

    结合数据库和snowflake的唯一ID方案,可以参考业界较为成熟的解法:Leaf——美团点评分布式ID生成系统,并考虑到了高可用、容灾、分布式下时钟等问题。

    在Python中使用

    import uuid
    
    
    print(uuid.uuid1())  # 版本一:时间戳和MAC地址
    # 51927c2a-7974-11ea-953f-54e1adeabc32  54e1adeabc32是MAC地址
    
    print(uuid.uuid3(uuid.NAMESPACE_OID, 'timeashore'))  # 版本三:散列(MD5)命名空间和名称
    # b92ac374-c149-35ba-9ed4-f8b4d9cd8e85
    
    print(uuid.uuid4())  # 版本四:随机数
    # 4d9c6aa2-95fa-4ac4-b30d-a520bf5684f2
    
    print(uuid.uuid5(uuid.NAMESPACE_OID, 'timeashore'))  # 版本五:散列(SHA1)命名空间和名称
    # 6e107881-f2ef-5a1e-a458-1c8047070e08
    # 命名空间不是输入的,预置NAMESPACE_OID, NAMESPACE_URL, NAMESPACE_DNS,它们也是一个UUID
    

    RFC 4122 保留了“DCE security” UUID 的“版本2”;但它没有提供任何细节。因此,许多 UUID 实现省略了“版本2”。

    使用较多的是版本1和版本4,因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5。(soc用的随机数)

    参考

    wiki/通用唯一识别码

  • 相关阅读:
    NYOJ-开灯问题
    cocos2dx 3.0 飞机大战
    Java 实现享元(Flyweight)模式
    MongoDB 操作手冊CRUD查询指针
    均值滤波
    cxf调用c#的webservice
    SharePoint 2013 术语和术语集介绍
    Unity3d 网络编程(二)(Unity3d内建网络各项參数介绍)
    linux服务器在运行210天左右宕机
    好的用户界面-界面设计的一些技巧
  • 原文地址:https://www.cnblogs.com/ldy-miss/p/12661305.html
Copyright © 2011-2022 走看看