• 唯一标识


     

    全局唯一标识符

    全局唯一标识符,简称GUID,是一种由算法生成的唯一标识,通常表示成3216进制数字(09AF)组成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它实质上是一个128位长的二进制整数。GUID一词有时也专指微软对UUID标准的实现。

    GUID的主要目的是产生完全唯一的数字。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUIDGUID的总数也足够大,达到了2^128个,所以随机生成两个相同GUID的可能性是非常小的,但并不为0

    由于GUID生成的算法和内部组成结构有多种,且网络上很难找到它详细的生成算法,所以这里将不做介绍。

    MongoDBObjectId

    1)     Time

    时间戳。将objectid的前4位进行提取,然后按照十六进制转为十进制这个数字就是一个时间戳。通过时间戳的转换,可以很容易看清时间格式。

    2)    Machine

    机器。接下来的三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器hash值,确保在分布式中不造成冲突,这也就是在同一台机器生成的objectId中间的字符串都是一模一样的原因。

    3)    PID

    进程ID。上面的Machine是为了确保在不同机器产生的objectId不冲突,而pid就是为了在同一台机器不同的mongodb进程产生了objectId不冲突,接下来的两位就是产生objectId的进程标识符。

    4)    INC

    自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成objectId不冲突,后面的三个字节是一个自动增加的计数器,用来确保在同一秒内产生的objectId也不会发现冲突,允许2^24等于16777216条记录的唯一性。

    总的来看,objectId的前4个字节时间戳,记录了数据创建的时间;接下来3个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的objectId;后2个字节的进程id,决定了在同一台机器下,不同mongodb进程产生不同的objectId;最后通过3个字节的自增计数器,确保同一秒内产生objectId的唯一性。ObjectId的这个主键生成策略,很好地解决了在分布式环境下高并发情况主键唯一性问题

    学习借鉴

    objectId生成规则,我们可以根据实际需求来创建自己的唯一标识,比如:如果不需要考虑并发情况下,我们可以按时间四字节,自增ID五字节这样来组织生成唯一标识。

    数据的展示

    我们知道,二进制转8进制,可以使用421法,转16进制可以使用8421法,八进制由0-7数字组成,16进制由0-9 A-F组成,如:(10111010)2=(272)8=(BA)16。同理,我们可以推出有7进制(周一到周天)26进制(a-z)52进制(a-z A-Z),64进制(a-z,A-Z,0-9,/,+)等及其计算方法。

    由转换规则,可以知道,283位对1位,2164位对1232,就是5位对1位,264就是6位对1位,掌握这个规则对我为接下来减少数据表现位数很有用。我们知道,GUID128位二进制表示的(16字节)可以转换成3216进制表示的字符串或2264进制表示的字符串,就是这样得出来的。

    GUID无损压缩

    网络上流行一种做法:

    byte[] buffer = Guid.NewGuid().ToByteArray();  

    long long_guid=BitConverter.ToInt64(buffer, 0)

    这样就会得到一个类似于  5472976187161141196 19位长度的数字序列。对这串十进制数还可以在转换,转换成64进制数表示,可以缩到12

    两个疑问:

    l  是无损压缩,那么可以还原吗

    l  由上一章节的推理,怎么可以缩到用19位数字表示呢?

    MSDN查找BitConverter.ToInt64方法,我们发现这样一段话:

    ToInt64 方法将字节转换为索引中startIndexstartIndex + 7,以Int64的值。字节数组中的顺序必须反映字节排序方式的计算机系统的体系结构 ; 有关详细信息,请参阅注解部分中的BitConverter类主题。

     

    真现大白了,原来ToInt64方法,只取bufferstartIndex开始向后加7个字节的值。也就是说,我们16字节的高8个字节被忽略掉了。GUID理想情况下,要2^128个数据才会出现冲突,而转换后,把字节数半,也就是2^64数据就会出现冲突。

    使用低8字节的GUID,我的机器运行1个多小时,计算2千万以上数据,没有出现过冲突。

     

    总结

    1.     如果低八字节的GUID满足需求,那我们可以使用低八字节来表示唯一标识位数我们可以转换成64进制表示,也就是12位就可以了。

    2.     某些系统,需要并发产生唯一标识,我们可以根据objectid生成规则,在根据实际需求生成唯一标识。

  • 相关阅读:
    js+jq 淡入淡出轮播(点击+定时+鼠标进入移出事件)
    DBCA静默方式建库
    Oracle 11g常用管理命令(用户、表空间、权限)
    RedHat 7.3 Oracle 12.2.0.1 RAC 安装手册(转)
    rsyslog和logrotate服务
    Linux 之 rsyslog 系统日志转发
    Flatty Shadow图标自动产生器——在线生成各种扁平化 ICON
    助力前端开发——20个精心挑选新鲜好用的前端开发工具
    15款新鲜出炉的实用网页设计工具
    提供免费可商用的优秀背景视频素材——COVERR
  • 原文地址:https://www.cnblogs.com/tqlin/p/2870321.html
Copyright © 2020-2023  润新知