zoukankan      html  css  js  c++  java
  • 唯一标识

     

    全局唯一标识符

    全局唯一标识符,简称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生成规则,在根据实际需求生成唯一标识。

  • 相关阅读:
    231. Power of Two
    204. Count Primes
    205. Isomorphic Strings
    203. Remove Linked List Elements
    179. Largest Number
    922. Sort Array By Parity II
    350. Intersection of Two Arrays II
    242. Valid Anagram
    164. Maximum Gap
    147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/tqlin/p/2870321.html
Copyright © 2011-2022 走看看